Merge pull request #586 from bviktor/authcleanup
Login and network list cleanup
This commit is contained in:
commit
69c2893234
@ -184,7 +184,7 @@ dnl *********************************************************************
|
||||
dnl ** GLIB *************************************************************
|
||||
dnl *********************************************************************
|
||||
|
||||
AM_PATH_GLIB_2_0(2.14.0, glib=yes, glib=no)
|
||||
AM_PATH_GLIB_2_0(2.28.0, glib=yes, glib=no)
|
||||
if test "$glib" = no; then
|
||||
AC_MSG_ERROR(Cannot find GLib!)
|
||||
fi
|
||||
@ -199,7 +199,7 @@ dnl *********************************************************************
|
||||
|
||||
# we might get undefined macro without this test
|
||||
if test "$gtkfe" = yes ; then
|
||||
AM_PATH_GTK_2_0(2.14.0, havegtk=yes, havegtk=no)
|
||||
AM_PATH_GTK_2_0(2.24.0, havegtk=yes, havegtk=no)
|
||||
|
||||
if test "$havegtk" = no; then
|
||||
gtkfe=no
|
||||
|
@ -2,10 +2,10 @@
|
||||
|
||||
Just some tips if you're going to help with HexChat code (patches etc):
|
||||
|
||||
* Use tabs, not spaces, to indent code.
|
||||
* Use tabs, not spaces, to indent and align code.
|
||||
|
||||
* Use a tab size of 3 (most editors will let you choose this).
|
||||
Type :set ts=3 in vim/gvim.
|
||||
* Use a tab size of 4 (most editors will let you choose this).
|
||||
Type :set ts=4 in vim/gvim.
|
||||
|
||||
* Try to stick to the same consistant coding style (vertically aligned braces, a space after if, while, functions etc.):
|
||||
|
||||
|
@ -21,8 +21,8 @@ in general. HexChat runs on most BSD and POSIX compliant operating systems.
|
||||
|
||||
## Requirements:
|
||||
|
||||
* GTK+ 2.14
|
||||
* GLib 2.14
|
||||
* GTK+ 2.24
|
||||
* GLib 2.28
|
||||
|
||||
HexChat is known to work on, at least:
|
||||
|
||||
|
@ -66,15 +66,6 @@
|
||||
#define BIG_STR_TO_INT(x) strtoul(x,NULL,10)
|
||||
#endif
|
||||
|
||||
/* This is practically copy-paste from gstdio.h.
|
||||
* GStatBuf was added in 2.26. On Win32 we already use that,
|
||||
* so we only gotta check this on Unix */
|
||||
#ifndef WIN32
|
||||
#if !GLIB_CHECK_VERSION(2,26,0)
|
||||
typedef struct stat GStatBuf;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
static char *dcctypes[] = { "SEND", "RECV", "CHAT", "CHAT" };
|
||||
|
||||
struct dccstat_info dccstat[] = {
|
||||
|
@ -479,7 +479,7 @@ typedef struct server
|
||||
void (*p_ns_identify)(struct server *, char *pass);
|
||||
void (*p_ns_ghost)(struct server *, char *usname, char *pass);
|
||||
void (*p_join)(struct server *, char *channel, char *key);
|
||||
void (*p_join_list)(struct server *, GSList *channels, GSList *keys);
|
||||
void (*p_join_list)(struct server *, GSList *favorites);
|
||||
void (*p_login)(struct server *, char *user, char *realname);
|
||||
void (*p_join_info)(struct server *, char *channel);
|
||||
void (*p_mode)(struct server *, char *target, char *mode);
|
||||
@ -527,14 +527,12 @@ typedef struct server
|
||||
char hostname[128]; /* real ip number */
|
||||
char servername[128]; /* what the server says is its name */
|
||||
char password[86];
|
||||
char sasluser[32]; /* this is just a buffer for network->user */
|
||||
char saslpassword[86]; /* we could reuse password but then we couldn't guarantee NickServ doesn't register first */
|
||||
char nick[NICKLEN];
|
||||
char linebuf[2048]; /* RFC says 512 chars including \r\n */
|
||||
char *last_away_reason;
|
||||
int pos; /* current position in linebuf */
|
||||
int nickcount;
|
||||
int nickservtype; /* 0=/MSG nickserv 1=/NICKSERV 2=/NS */
|
||||
int loginmethod; /* see login_types[] */
|
||||
|
||||
char *chantypes; /* for 005 numeric - free me */
|
||||
char *chanmodes; /* for 005 numeric - free me */
|
||||
@ -568,7 +566,7 @@ typedef struct server
|
||||
time_t away_time; /* when we were marked away */
|
||||
|
||||
char *encoding; /* NULL for system */
|
||||
char *autojoin; /* list of channels & keys to join */
|
||||
GSList *favlist; /* list of channels & keys to join */
|
||||
|
||||
unsigned int motd_skipped:1;
|
||||
unsigned int connected:1;
|
||||
|
@ -1066,38 +1066,26 @@ inbound_nameslist_end (server *serv, char *chan)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
static void
|
||||
check_autojoin_channels (server *serv)
|
||||
{
|
||||
char *po;
|
||||
int i = 0;
|
||||
session *sess;
|
||||
GSList *list = sess_list;
|
||||
int i = 0;
|
||||
GSList *channels, *keys;
|
||||
GSList *sess_channels = NULL; /* joined channels that are not in the favorites list */
|
||||
favchannel *fav;
|
||||
|
||||
/* shouldnt really happen, the io tag is destroyed in server.c */
|
||||
/* shouldn't really happen, the io tag is destroyed in server.c */
|
||||
if (!is_server (serv))
|
||||
return FALSE;
|
||||
|
||||
/* send auto join list */
|
||||
if (serv->autojoin)
|
||||
{
|
||||
joinlist_split (serv->autojoin, &channels, &keys);
|
||||
serv->p_join_list (serv, channels, keys);
|
||||
joinlist_free (channels, keys);
|
||||
|
||||
free (serv->autojoin);
|
||||
serv->autojoin = NULL;
|
||||
i++;
|
||||
return;
|
||||
}
|
||||
|
||||
/* this is really only for re-connects when you
|
||||
* join channels not in the auto-join list. */
|
||||
channels = NULL;
|
||||
keys = NULL;
|
||||
/* If there's a session (i.e. this is a reconnect), autojoin to everything that was open previously. */
|
||||
while (list)
|
||||
{
|
||||
sess = list->data;
|
||||
|
||||
if (sess->server == serv)
|
||||
{
|
||||
if (sess->willjoinchannel[0] != 0)
|
||||
@ -1105,39 +1093,54 @@ check_autojoin_channels (server *serv)
|
||||
strcpy (sess->waitchannel, sess->willjoinchannel);
|
||||
sess->willjoinchannel[0] = 0;
|
||||
|
||||
po = strchr (sess->waitchannel, ',');
|
||||
if (po)
|
||||
*po = 0;
|
||||
po = strchr (sess->waitchannel, ' ');
|
||||
if (po)
|
||||
*po = 0;
|
||||
fav = servlist_favchan_find (serv->network, sess->waitchannel, NULL); /* Is this channel in our favorites? */
|
||||
|
||||
/* There can be no gap between keys, list keyed chans first. */
|
||||
if (sess->channelkey[0] != 0)
|
||||
/* session->channelkey is initially unset for channels joined from the favorites. You have to fill them up manually from favorites settings. */
|
||||
if (fav)
|
||||
{
|
||||
channels = g_slist_prepend (channels, g_strdup (sess->waitchannel));
|
||||
keys = g_slist_prepend (keys, g_strdup (sess->channelkey));
|
||||
/* session->channelkey is set if there was a key change during the session. In that case, use the session key, not the one from favorites. */
|
||||
if (fav->key && !strlen (sess->channelkey))
|
||||
{
|
||||
safe_strcpy (sess->channelkey, fav->key, sizeof (sess->channelkey));
|
||||
}
|
||||
}
|
||||
|
||||
/* for easier checks, ensure that favchannel->key is just NULL when session->channelkey is empty i.e. '' */
|
||||
if (strlen (sess->channelkey))
|
||||
{
|
||||
sess_channels = servlist_favchan_listadd (sess_channels, sess->waitchannel, sess->channelkey);
|
||||
}
|
||||
else
|
||||
{
|
||||
channels = g_slist_append (channels, g_strdup (sess->waitchannel));
|
||||
keys = g_slist_append (keys, g_strdup (sess->channelkey));
|
||||
sess_channels = servlist_favchan_listadd (sess_channels, sess->waitchannel, NULL);
|
||||
}
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
list = list->next;
|
||||
}
|
||||
|
||||
if (channels)
|
||||
if (sess_channels)
|
||||
{
|
||||
serv->p_join_list (serv, channels, keys);
|
||||
joinlist_free (channels, keys);
|
||||
serv->p_join_list (serv, sess_channels);
|
||||
g_slist_free_full (sess_channels, (GDestroyNotify) servlist_favchan_free);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* If there's no session, just autojoin to favorites. */
|
||||
if (serv->favlist)
|
||||
{
|
||||
serv->p_join_list (serv, serv->favlist);
|
||||
i++;
|
||||
|
||||
/* FIXME this is not going to work and is not needed either. server_free() does the job already. */
|
||||
/* g_slist_free_full (serv->favlist, (GDestroyNotify) servlist_favchan_free); */
|
||||
}
|
||||
}
|
||||
|
||||
serv->joindelay_tag = 0;
|
||||
fe_server_event (serv, FE_SE_LOGGEDIN, i);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
void
|
||||
@ -1367,9 +1370,28 @@ inbound_exec_eom_cmd (char *str, void *sess)
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
inbound_nickserv_login (server *serv)
|
||||
{
|
||||
/* this could grow ugly, but let's hope there won't be new NickServ types */
|
||||
switch (serv->loginmethod)
|
||||
{
|
||||
case LOGIN_MSG_NICKSERV:
|
||||
case LOGIN_NICKSERV:
|
||||
case LOGIN_NS:
|
||||
case LOGIN_MSG_NS:
|
||||
case LOGIN_AUTH:
|
||||
return 1;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
inbound_login_end (session *sess, char *text)
|
||||
{
|
||||
GSList *cmdlist;
|
||||
commandentry *cmd;
|
||||
server *serv = sess->server;
|
||||
|
||||
if (!serv->end_of_motd)
|
||||
@ -1384,35 +1406,48 @@ inbound_login_end (session *sess, char *text)
|
||||
if (serv->network)
|
||||
{
|
||||
/* there may be more than 1, separated by \n */
|
||||
if (((ircnet *)serv->network)->command)
|
||||
token_foreach (((ircnet *)serv->network)->command, '\n',
|
||||
inbound_exec_eom_cmd, sess);
|
||||
|
||||
cmdlist = ((ircnet *)serv->network)->commandlist;
|
||||
while (cmdlist)
|
||||
{
|
||||
cmd = cmdlist->data;
|
||||
inbound_exec_eom_cmd (cmd->command, sess);
|
||||
cmdlist = cmdlist->next;
|
||||
}
|
||||
|
||||
/* send nickserv password */
|
||||
if (((ircnet *)serv->network)->nickserv)
|
||||
serv->p_ns_identify (serv, ((ircnet *)serv->network)->nickserv);
|
||||
if (((ircnet *)serv->network)->pass && inbound_nickserv_login (serv))
|
||||
{
|
||||
serv->p_ns_identify (serv, ((ircnet *)serv->network)->pass);
|
||||
}
|
||||
}
|
||||
|
||||
/* send JOIN now or wait? */
|
||||
if (serv->network && ((ircnet *)serv->network)->nickserv &&
|
||||
prefs.hex_irc_join_delay)
|
||||
serv->joindelay_tag = fe_timeout_add (prefs.hex_irc_join_delay * 1000,
|
||||
check_autojoin_channels, serv);
|
||||
if (serv->network && ((ircnet *)serv->network)->pass && prefs.hex_irc_join_delay && inbound_nickserv_login (serv))
|
||||
{
|
||||
serv->joindelay_tag = fe_timeout_add (prefs.hex_irc_join_delay * 1000, check_autojoin_channels, serv);
|
||||
}
|
||||
else
|
||||
{
|
||||
check_autojoin_channels (serv);
|
||||
}
|
||||
|
||||
if (serv->supports_watch || serv->supports_monitor)
|
||||
{
|
||||
notify_send_watches (serv);
|
||||
}
|
||||
|
||||
serv->end_of_motd = TRUE;
|
||||
}
|
||||
|
||||
if (prefs.hex_irc_skip_motd && !serv->motd_skipped)
|
||||
{
|
||||
serv->motd_skipped = TRUE;
|
||||
EMIT_SIGNAL (XP_TE_MOTDSKIP, serv->server_session, NULL, NULL,
|
||||
NULL, NULL, 0);
|
||||
EMIT_SIGNAL (XP_TE_MOTDSKIP, serv->server_session, NULL, NULL, NULL, NULL, 0);
|
||||
return;
|
||||
}
|
||||
EMIT_SIGNAL (XP_TE_MOTD, serv->server_session, text, NULL,
|
||||
NULL, NULL, 0);
|
||||
|
||||
EMIT_SIGNAL (XP_TE_MOTD, serv->server_session, text, NULL, NULL, NULL, 0);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -1111,11 +1111,6 @@ hexchat_get_info (hexchat_plugin *ph, const char *id)
|
||||
case 0x339763: /* nick */
|
||||
return sess->server->nick;
|
||||
|
||||
case 0x438fdf9: /* nickserv */
|
||||
if (sess->server->network)
|
||||
return ((ircnet *)sess->server->network)->nickserv;
|
||||
return NULL;
|
||||
|
||||
case 0xca022f43: /* server */
|
||||
if (!sess->server->connected)
|
||||
return NULL;
|
||||
|
@ -42,6 +42,7 @@
|
||||
#include "util.h"
|
||||
#include "hexchatc.h"
|
||||
#include "url.h"
|
||||
#include "servlist.h"
|
||||
|
||||
|
||||
static void
|
||||
@ -49,7 +50,7 @@ irc_login (server *serv, char *user, char *realname)
|
||||
{
|
||||
tcp_sendf (serv, "CAP LS\r\n"); /* start with CAP LS as Charybdis sasl.txt suggests */
|
||||
|
||||
if (serv->password[0])
|
||||
if (serv->password[0] && serv->loginmethod == LOGIN_PASS)
|
||||
{
|
||||
tcp_sendf (serv, "PASS %s\r\n", serv->password);
|
||||
}
|
||||
@ -64,21 +65,23 @@ static void
|
||||
irc_nickserv (server *serv, char *cmd, char *arg1, char *arg2, char *arg3)
|
||||
{
|
||||
/* are all ircd authors idiots? */
|
||||
switch (serv->nickservtype)
|
||||
switch (serv->loginmethod)
|
||||
{
|
||||
case 0:
|
||||
case LOGIN_MSG_NICKSERV:
|
||||
tcp_sendf (serv, "PRIVMSG NICKSERV :%s %s%s%s\r\n", cmd, arg1, arg2, arg3);
|
||||
break;
|
||||
case 1:
|
||||
case LOGIN_NICKSERV:
|
||||
tcp_sendf (serv, "NICKSERV %s %s%s%s\r\n", cmd, arg1, arg2, arg3);
|
||||
break;
|
||||
case 2:
|
||||
#if 0
|
||||
case LOGIN_NS:
|
||||
tcp_sendf (serv, "NS %s %s%s%s\r\n", cmd, arg1, arg2, arg3);
|
||||
break;
|
||||
case 3:
|
||||
#endif
|
||||
case LOGIN_MSG_NS:
|
||||
tcp_sendf (serv, "PRIVMSG NS :%s %s%s%s\r\n", cmd, arg1, arg2, arg3);
|
||||
break;
|
||||
case 4:
|
||||
case LOGIN_AUTH:
|
||||
/* why couldn't QuakeNet implement one of the existing ones? */
|
||||
tcp_sendf (serv, "AUTH %s %s\r\n", arg1, arg2);
|
||||
}
|
||||
@ -87,7 +90,7 @@ irc_nickserv (server *serv, char *cmd, char *arg1, char *arg2, char *arg3)
|
||||
static void
|
||||
irc_ns_identify (server *serv, char *pass)
|
||||
{
|
||||
if (serv->nickservtype == 4) /* QuakeNet needs to do everything in its own ways... */
|
||||
if (serv->loginmethod == LOGIN_AUTH) /* QuakeNet needs to do everything in its own ways... */
|
||||
{
|
||||
irc_nickserv (serv, "", serv->nick, pass, "");
|
||||
}
|
||||
@ -100,8 +103,10 @@ irc_ns_identify (server *serv, char *pass)
|
||||
static void
|
||||
irc_ns_ghost (server *serv, char *usname, char *pass)
|
||||
{
|
||||
if (serv->nickservtype != 4)
|
||||
if (serv->loginmethod != LOGIN_AUTH)
|
||||
{
|
||||
irc_nickserv (serv, "GHOST", usname, " ", pass);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
@ -114,118 +119,97 @@ irc_join (server *serv, char *channel, char *key)
|
||||
}
|
||||
|
||||
static void
|
||||
irc_join_list_flush (server *serv, GString *c, GString *k)
|
||||
irc_join_list_flush (server *serv, GString *channels, GString *keys, int send_keys)
|
||||
{
|
||||
char *chanstr, *keystr;
|
||||
char *chanstr;
|
||||
char *keystr;
|
||||
|
||||
chanstr = g_string_free (c, FALSE);
|
||||
keystr = g_string_free (k, FALSE);
|
||||
if (chanstr[0])
|
||||
chanstr = g_string_free (channels, FALSE); /* convert our strings to char arrays */
|
||||
keystr = g_string_free (keys, FALSE);
|
||||
|
||||
if (send_keys)
|
||||
{
|
||||
if (keystr[0])
|
||||
tcp_sendf (serv, "JOIN %s %s\r\n", chanstr, keystr);
|
||||
else
|
||||
tcp_sendf (serv, "JOIN %s\r\n", chanstr);
|
||||
tcp_sendf (serv, "JOIN %s %s\r\n", chanstr, keystr); /* send the actual command */
|
||||
}
|
||||
else
|
||||
{
|
||||
tcp_sendf (serv, "JOIN %s\r\n", chanstr); /* send the actual command */
|
||||
}
|
||||
|
||||
g_free (chanstr);
|
||||
g_free (keystr);
|
||||
}
|
||||
|
||||
/* join a whole list of channels & keys, split to multiple lines
|
||||
* to get around 512 limit */
|
||||
/* Join a whole list of channels & keys, split to multiple lines
|
||||
* to get around the 512 limit.
|
||||
*/
|
||||
|
||||
static void
|
||||
irc_join_list (server *serv, GSList *channels, GSList *keys)
|
||||
irc_join_list (server *serv, GSList *favorites)
|
||||
{
|
||||
GSList *clist;
|
||||
GSList *klist;
|
||||
GString *c = g_string_new (NULL);
|
||||
GString *k = g_string_new (NULL);
|
||||
int len;
|
||||
int add;
|
||||
int i, j;
|
||||
int first_item = 1; /* determine whether we add commas or not */
|
||||
int send_keys = 0; /* if none of our channels have keys, we can omit the 'x' fillers altogether */
|
||||
int len = 9; /* JOIN<space>channels<space>keys\r\n\0 */
|
||||
favchannel *fav;
|
||||
GString *chanlist = g_string_new (NULL);
|
||||
GString *keylist = g_string_new (NULL);
|
||||
GSList *favlist;
|
||||
|
||||
i = j = 0;
|
||||
len = 9; /* "JOIN<space><space>\r\n" */
|
||||
clist = channels;
|
||||
klist = keys;
|
||||
favlist = favorites;
|
||||
|
||||
while (clist)
|
||||
while (favlist)
|
||||
{
|
||||
/* measure how many bytes this channel would add... */
|
||||
if (1)
|
||||
fav = favlist->data;
|
||||
|
||||
len += strlen (fav->name);
|
||||
if (fav->key)
|
||||
{
|
||||
add = strlen (clist->data);
|
||||
if (i != 0)
|
||||
add++; /* comma */
|
||||
len += strlen (fav->key);
|
||||
}
|
||||
|
||||
if (klist->data)
|
||||
if (len >= 512) /* command length exceeds the IRC hard limit, flush it and start from scratch */
|
||||
{
|
||||
add += strlen (klist->data);
|
||||
}
|
||||
else
|
||||
{
|
||||
add++; /* 'x' filler */
|
||||
}
|
||||
irc_join_list_flush (serv, chanlist, keylist, send_keys);
|
||||
|
||||
if (j != 0)
|
||||
add++; /* comma */
|
||||
chanlist = g_string_new (NULL);
|
||||
keylist = g_string_new (NULL);
|
||||
|
||||
/* too big? dump buffer and start a fresh one */
|
||||
if (len + add > 512)
|
||||
{
|
||||
irc_join_list_flush (serv, c, k);
|
||||
|
||||
c = g_string_new (NULL);
|
||||
k = g_string_new (NULL);
|
||||
i = j = 0;
|
||||
len = 9;
|
||||
first_item = 1; /* list dumped, omit commas once again */
|
||||
send_keys = 0; /* also omit keys until we actually find one */
|
||||
}
|
||||
|
||||
/* now actually add it to our GStrings */
|
||||
if (1)
|
||||
if (!first_item)
|
||||
{
|
||||
add = strlen (clist->data);
|
||||
if (i != 0)
|
||||
{
|
||||
add++;
|
||||
g_string_append_c (c, ',');
|
||||
}
|
||||
g_string_append (c, clist->data);
|
||||
i++;
|
||||
/* This should be done before the length check, but channel names
|
||||
* are already at least 2 characters long so it would trigger the
|
||||
* flush anyway.
|
||||
*/
|
||||
len += 2;
|
||||
|
||||
/* add separators but only if it's not the 1st element */
|
||||
g_string_append_c (chanlist, ',');
|
||||
g_string_append_c (keylist, ',');
|
||||
}
|
||||
|
||||
if (klist->data)
|
||||
g_string_append (chanlist, fav->name);
|
||||
|
||||
if (fav->key)
|
||||
{
|
||||
add += strlen (klist->data);
|
||||
if (j != 0)
|
||||
{
|
||||
add++;
|
||||
g_string_append_c (k, ',');
|
||||
}
|
||||
g_string_append (k, klist->data);
|
||||
j++;
|
||||
g_string_append (keylist, fav->key);
|
||||
send_keys = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
add++;
|
||||
if (j != 0)
|
||||
{
|
||||
add++;
|
||||
g_string_append_c (k, ',');
|
||||
}
|
||||
g_string_append_c (k, 'x');
|
||||
j++;
|
||||
g_string_append_c (keylist, 'x'); /* 'x' filler for keyless channels so that our JOIN command is always well-formatted */
|
||||
}
|
||||
|
||||
len += add;
|
||||
|
||||
klist = klist->next;
|
||||
clist = clist->next;
|
||||
first_item = 0;
|
||||
favlist = favlist->next;
|
||||
}
|
||||
|
||||
irc_join_list_flush (serv, c, k);
|
||||
irc_join_list_flush (serv, chanlist, keylist, send_keys);
|
||||
g_slist_free (favlist);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -1218,10 +1202,23 @@ process_named_msg (session *sess, char *type, char *word[], char *word_eol[])
|
||||
if (strstr (word_eol[5], "sasl") != 0)
|
||||
{
|
||||
serv->have_sasl = TRUE;
|
||||
EMIT_SIGNAL (XP_TE_SASLAUTH, serv->server_session, sess->server->sasluser, NULL, NULL, NULL, 0);
|
||||
EMIT_SIGNAL
|
||||
(
|
||||
XP_TE_SASLAUTH,
|
||||
serv->server_session,
|
||||
(((ircnet *)sess->server->network)->user) ? (((ircnet *)sess->server->network)->user) : prefs.hex_irc_user_name,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
0
|
||||
);
|
||||
tcp_send_len (serv, "AUTHENTICATE PLAIN\r\n", 20);
|
||||
|
||||
pass = encode_sasl_pass (sess->server->sasluser, sess->server->saslpassword);
|
||||
pass = encode_sasl_pass
|
||||
(
|
||||
(((ircnet *)sess->server->network)->user) ? (((ircnet *)sess->server->network)->user) : prefs.hex_irc_user_name,
|
||||
sess->server->password
|
||||
);
|
||||
tcp_sendf (sess->server, "AUTHENTICATE %s\r\n", pass);
|
||||
free (pass);
|
||||
}
|
||||
@ -1259,8 +1256,8 @@ process_named_msg (session *sess, char *type, char *word[], char *word_eol[])
|
||||
strcat (buffer, "extended-join ");
|
||||
want_cap = 1;
|
||||
}
|
||||
/* if the SASL password is set, request SASL auth */
|
||||
if (strstr (word_eol[5], "sasl") != 0 && strlen (sess->server->saslpassword) != 0)
|
||||
/* if the SASL password is set AND auth mode is set to SASL, request SASL auth */
|
||||
if (strstr (word_eol[5], "sasl") != 0 && strlen (sess->server->password) != 0 && serv->loginmethod == LOGIN_SASL)
|
||||
{
|
||||
strcat (buffer, "sasl ");
|
||||
want_cap = 1;
|
||||
|
@ -2030,8 +2030,8 @@ server_free (server *serv)
|
||||
free (serv->last_away_reason);
|
||||
if (serv->encoding)
|
||||
free (serv->encoding);
|
||||
if (serv->autojoin)
|
||||
free (serv->autojoin);
|
||||
if (serv->favlist)
|
||||
g_slist_free_full (serv->favlist, (GDestroyNotify) servlist_favchan_free);
|
||||
|
||||
fe_server_callback (serv);
|
||||
|
||||
|
@ -43,7 +43,7 @@ struct defaultserver
|
||||
char *host;
|
||||
char *channel;
|
||||
char *charset;
|
||||
int nsmode; /* default NickServ type */
|
||||
int loginmode; /* default authentication type */
|
||||
};
|
||||
|
||||
static const struct defaultserver def[] =
|
||||
@ -167,7 +167,7 @@ static const struct defaultserver def[] =
|
||||
{0, "irc.criten.net"},
|
||||
{0, "irc.eu.criten.net"},
|
||||
|
||||
{"DALnet", 0, 0, 0, 2},
|
||||
{"DALnet", 0},
|
||||
{0, "irc.dal.net"},
|
||||
{0, "irc.eu.dal.net"},
|
||||
|
||||
@ -245,7 +245,7 @@ static const struct defaultserver def[] =
|
||||
{0, "irc.ggn.net"},
|
||||
{0, "irc.vendetta.com"},
|
||||
|
||||
{"freenode", 0, "#hexchat"},
|
||||
{"freenode", 0, "#hexchat", 0, LOGIN_SASL},
|
||||
#ifdef USE_OPENSSL
|
||||
{0, "irc.freenode.net/+6697"},
|
||||
#endif
|
||||
@ -263,7 +263,7 @@ static const struct defaultserver def[] =
|
||||
/* {0, "sprynet.us.galaxynet.org"},
|
||||
{0, "atlanta.ga.us.galaxynet.org"},*/
|
||||
|
||||
{"GameSurge", 0, 0, 0, 2},
|
||||
{"GameSurge", 0},
|
||||
{0, "irc.gamesurge.net"},
|
||||
|
||||
/* {"GamesNET", 0},
|
||||
@ -426,7 +426,7 @@ static const struct defaultserver def[] =
|
||||
{0, "nfsi.ptnet.org"},
|
||||
{0, "fctunl.ptnet.org"},
|
||||
|
||||
{"QuakeNet", 0, 0, 0, 5},
|
||||
{"QuakeNet", 0, 0, 0, LOGIN_AUTH},
|
||||
{0, "irc.quakenet.org"},
|
||||
{0, "irc.se.quakenet.org"},
|
||||
{0, "irc.dk.quakenet.org"},
|
||||
@ -460,7 +460,7 @@ static const struct defaultserver def[] =
|
||||
{"Rizon", 0},
|
||||
{0, "irc.rizon.net"},
|
||||
|
||||
{"RusNet", 0, 0, "KOI8-R (Cyrillic)", 2},
|
||||
{"RusNet", 0, 0, "KOI8-R (Cyrillic)"},
|
||||
{0, "irc.tomsk.net"},
|
||||
{0, "irc.rinet.ru"},
|
||||
{0, "irc.run.net"},
|
||||
@ -545,7 +545,7 @@ static const struct defaultserver def[] =
|
||||
{0, "us.undernet.org"},
|
||||
{0, "eu.undernet.org"},
|
||||
|
||||
{"UniBG", 0, 0, 0, 4},
|
||||
{"UniBG", 0, 0, 0, LOGIN_MSG_NS},
|
||||
{0, "irc.lirex.com"},
|
||||
{0, "irc.naturella.com"},
|
||||
{0, "irc.spnet.net"},
|
||||
@ -581,6 +581,55 @@ static const struct defaultserver def[] =
|
||||
|
||||
GSList *network_list = 0;
|
||||
|
||||
#if !GLIB_CHECK_VERSION(2,34,0)
|
||||
#define g_slist_copy_deep servlist_slist_copy_deep
|
||||
/* FIXME copy-paste from gslist.c, should be dumped sometime */
|
||||
static GSList*
|
||||
servlist_slist_copy_deep (GSList *list, GCopyFunc func, gpointer user_data)
|
||||
{
|
||||
GSList *new_list = NULL;
|
||||
|
||||
if (list)
|
||||
{
|
||||
GSList *last;
|
||||
|
||||
new_list = g_slice_new (GSList);
|
||||
if (func)
|
||||
new_list->data = func (list->data, user_data);
|
||||
else
|
||||
new_list->data = list->data;
|
||||
last = new_list;
|
||||
list = list->next;
|
||||
while (list)
|
||||
{
|
||||
last->next = g_slice_new (GSList);
|
||||
last = last->next;
|
||||
if (func)
|
||||
last->data = func (list->data, user_data);
|
||||
else
|
||||
last->data = list->data;
|
||||
list = list->next;
|
||||
}
|
||||
last->next = NULL;
|
||||
}
|
||||
|
||||
return new_list;
|
||||
}
|
||||
#endif
|
||||
|
||||
favchannel *
|
||||
servlist_favchan_copy (favchannel *fav)
|
||||
{
|
||||
favchannel *newfav;
|
||||
|
||||
newfav = malloc (sizeof (favchannel));
|
||||
memset (newfav, 0, sizeof (favchannel));
|
||||
|
||||
newfav->name = g_strdup (fav->name);
|
||||
newfav->key = g_strdup (fav->key); /* g_strdup() can handle NULLs so no need to check it */
|
||||
|
||||
return newfav;
|
||||
}
|
||||
|
||||
void
|
||||
servlist_connect (session *sess, ircnet *net, gboolean join)
|
||||
@ -603,53 +652,39 @@ servlist_connect (session *sess, ircnet *net, gboolean join)
|
||||
return;
|
||||
ircserv = list->data;
|
||||
|
||||
/* incase a protocol switch is added to the servlist gui */
|
||||
/* in case a protocol switch is added to the servlist gui */
|
||||
server_fill_her_up (sess->server);
|
||||
|
||||
if (join)
|
||||
{
|
||||
sess->willjoinchannel[0] = 0;
|
||||
|
||||
if (net->autojoin)
|
||||
if (net->favchanlist)
|
||||
{
|
||||
if (serv->autojoin)
|
||||
free (serv->autojoin);
|
||||
serv->autojoin = strdup (net->autojoin);
|
||||
if (serv->favlist)
|
||||
{
|
||||
g_slist_free_full (serv->favlist, (GDestroyNotify) servlist_favchan_free);
|
||||
}
|
||||
serv->favlist = g_slist_copy_deep (net->favchanlist, (GCopyFunc) servlist_favchan_copy, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
if (net->nstype >= 1) /* once again, make sure gtk_combo_box_get_active() is not bugging us, just in case */
|
||||
if (net->logintype)
|
||||
{
|
||||
serv->nickservtype = net->nstype - 1; /* ircnet->nstype starts at 1, server->nickservtype starts at 0! */
|
||||
serv->loginmethod = net->logintype;
|
||||
}
|
||||
else
|
||||
{
|
||||
serv->nickservtype = 1; /* use /NickServ by default */
|
||||
serv->loginmethod = LOGIN_DEFAULT_REAL;
|
||||
}
|
||||
|
||||
serv->password[0] = 0;
|
||||
serv->sasluser[0] = 0;
|
||||
serv->saslpassword[0] = 0;
|
||||
|
||||
if (net->pass)
|
||||
{
|
||||
safe_strcpy (serv->password, net->pass, sizeof (serv->password));
|
||||
}
|
||||
|
||||
if (net->flags & FLAG_USE_GLOBAL || net->user == NULL)
|
||||
{
|
||||
strcpy (serv->sasluser, prefs.hex_irc_user_name);
|
||||
}
|
||||
else
|
||||
{
|
||||
safe_strcpy (serv->sasluser, net->user, sizeof (serv->sasluser));
|
||||
}
|
||||
|
||||
if (net->saslpass)
|
||||
{
|
||||
safe_strcpy (serv->saslpassword, net->saslpass, sizeof (serv->saslpassword));
|
||||
}
|
||||
|
||||
if (net->flags & FLAG_USE_GLOBAL)
|
||||
{
|
||||
strcpy (serv->nick, prefs.hex_irc_nick1);
|
||||
@ -820,7 +855,9 @@ servlist_server_find (ircnet *net, char *name, int *pos)
|
||||
if (strcmp (serv->hostname, name) == 0)
|
||||
{
|
||||
if (pos)
|
||||
{
|
||||
*pos = i;
|
||||
}
|
||||
return serv;
|
||||
}
|
||||
i++;
|
||||
@ -830,6 +867,56 @@ servlist_server_find (ircnet *net, char *name, int *pos)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
favchannel *
|
||||
servlist_favchan_find (ircnet *net, char *channel, int *pos)
|
||||
{
|
||||
GSList *list = net->favchanlist;
|
||||
favchannel *favchan;
|
||||
int i = 0;
|
||||
|
||||
while (list)
|
||||
{
|
||||
favchan = list->data;
|
||||
if (strcmp (favchan->name, channel) == 0)
|
||||
{
|
||||
if (pos)
|
||||
{
|
||||
*pos = i;
|
||||
}
|
||||
return favchan;
|
||||
}
|
||||
i++;
|
||||
list = list->next;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
commandentry *
|
||||
servlist_command_find (ircnet *net, char *cmd, int *pos)
|
||||
{
|
||||
GSList *list = net->commandlist;
|
||||
commandentry *entry;
|
||||
int i = 0;
|
||||
|
||||
while (list)
|
||||
{
|
||||
entry = list->data;
|
||||
if (strcmp (entry->command, cmd) == 0)
|
||||
{
|
||||
if (pos)
|
||||
{
|
||||
*pos = i;
|
||||
}
|
||||
return entry;
|
||||
}
|
||||
i++;
|
||||
list = list->next;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* find a network (e.g. (ircnet *) to "FreeNode") from a hostname
|
||||
(e.g. "irc.eu.freenode.net") */
|
||||
|
||||
@ -897,6 +984,60 @@ servlist_server_add (ircnet *net, char *name)
|
||||
return serv;
|
||||
}
|
||||
|
||||
commandentry *
|
||||
servlist_command_add (ircnet *net, char *cmd)
|
||||
{
|
||||
commandentry *entry;
|
||||
|
||||
entry = malloc (sizeof (commandentry));
|
||||
memset (entry, 0, sizeof (commandentry));
|
||||
entry->command = strdup (cmd);
|
||||
|
||||
net->commandlist = g_slist_append (net->commandlist, entry);
|
||||
|
||||
return entry;
|
||||
}
|
||||
|
||||
GSList *
|
||||
servlist_favchan_listadd (GSList *chanlist, char *channel, char *key)
|
||||
{
|
||||
favchannel *chan;
|
||||
|
||||
chan = malloc (sizeof (favchannel));
|
||||
memset (chan, 0, sizeof (favchannel));
|
||||
|
||||
chan->name = g_strdup (channel);
|
||||
chan->key = g_strdup (key);
|
||||
chanlist = g_slist_append (chanlist, chan);
|
||||
|
||||
return chanlist;
|
||||
}
|
||||
|
||||
void
|
||||
servlist_favchan_add (ircnet *net, char *channel)
|
||||
{
|
||||
int pos;
|
||||
char *name;
|
||||
char *key;
|
||||
|
||||
if (strchr (channel, ',') != NULL)
|
||||
{
|
||||
pos = (int) (strchr (channel, ',') - channel);
|
||||
name = g_strndup (channel, pos);
|
||||
key = g_strdup (channel + pos + 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
name = g_strdup (channel);
|
||||
key = NULL;
|
||||
}
|
||||
|
||||
net->favchanlist = servlist_favchan_listadd (net->favchanlist, name, key);
|
||||
|
||||
g_free (name);
|
||||
g_free (key);
|
||||
}
|
||||
|
||||
void
|
||||
servlist_server_remove (ircnet *net, ircserver *serv)
|
||||
{
|
||||
@ -917,6 +1058,35 @@ servlist_server_remove_all (ircnet *net)
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
servlist_command_free (commandentry *entry)
|
||||
{
|
||||
g_free (entry->command);
|
||||
g_free (entry);
|
||||
}
|
||||
|
||||
void
|
||||
servlist_command_remove (ircnet *net, commandentry *entry)
|
||||
{
|
||||
servlist_command_free (entry);
|
||||
net->commandlist = g_slist_remove (net->commandlist, entry);
|
||||
}
|
||||
|
||||
void
|
||||
servlist_favchan_free (favchannel *channel)
|
||||
{
|
||||
g_free (channel->name);
|
||||
g_free (channel->key);
|
||||
g_free (channel);
|
||||
}
|
||||
|
||||
void
|
||||
servlist_favchan_remove (ircnet *net, favchannel *channel)
|
||||
{
|
||||
servlist_favchan_free (channel);
|
||||
net->favchanlist = g_slist_remove (net->favchanlist, channel);
|
||||
}
|
||||
|
||||
static void
|
||||
free_and_clear (char *str)
|
||||
{
|
||||
@ -941,8 +1111,6 @@ servlist_cleanup (void)
|
||||
{
|
||||
net = list->data;
|
||||
free_and_clear (net->pass);
|
||||
free_and_clear (net->saslpass);
|
||||
free_and_clear (net->nickserv);
|
||||
}
|
||||
}
|
||||
|
||||
@ -964,12 +1132,10 @@ servlist_net_remove (ircnet *net)
|
||||
if (net->real)
|
||||
free (net->real);
|
||||
free_and_clear (net->pass);
|
||||
free_and_clear (net->saslpass);
|
||||
if (net->autojoin)
|
||||
free (net->autojoin);
|
||||
if (net->command)
|
||||
free (net->command);
|
||||
free_and_clear (net->nickserv);
|
||||
if (net->favchanlist)
|
||||
g_slist_free_full (net->favchanlist, (GDestroyNotify) servlist_favchan_free);
|
||||
if (net->commandlist)
|
||||
g_slist_free_full (net->commandlist, (GDestroyNotify) servlist_command_free);
|
||||
if (net->comment)
|
||||
free (net->comment);
|
||||
if (net->encoding)
|
||||
@ -983,7 +1149,9 @@ servlist_net_remove (ircnet *net)
|
||||
{
|
||||
serv = list->data;
|
||||
if (serv->network == net)
|
||||
{
|
||||
serv->network = NULL;
|
||||
}
|
||||
list = list->next;
|
||||
}
|
||||
}
|
||||
@ -1022,16 +1190,16 @@ servlist_load_defaults (void)
|
||||
net->encoding = strdup (IRC_DEFAULT_CHARSET);
|
||||
if (def[i].channel)
|
||||
{
|
||||
net->autojoin = strdup (def[i].channel);
|
||||
servlist_favchan_add (net, def[i].channel);
|
||||
}
|
||||
if (def[i].charset)
|
||||
{
|
||||
free (net->encoding);
|
||||
net->encoding = strdup (def[i].charset);
|
||||
}
|
||||
if (def[i].nsmode)
|
||||
if (def[i].loginmode)
|
||||
{
|
||||
net->nstype = def[i].nsmode;
|
||||
net->logintype = def[i].loginmode;
|
||||
}
|
||||
if (g_str_hash (def[i].network) == def_hash)
|
||||
{
|
||||
@ -1057,7 +1225,6 @@ servlist_load (void)
|
||||
FILE *fp;
|
||||
char buf[2048];
|
||||
int len;
|
||||
char *tmp;
|
||||
ircnet *net = NULL;
|
||||
|
||||
/* simple migration we will keep for a short while */
|
||||
@ -1100,43 +1267,55 @@ servlist_load (void)
|
||||
case 'P':
|
||||
net->pass = strdup (buf + 2);
|
||||
break;
|
||||
case 'A':
|
||||
net->saslpass = strdup (buf + 2);
|
||||
break;
|
||||
case 'J':
|
||||
net->autojoin = strdup (buf + 2);
|
||||
break;
|
||||
case 'C':
|
||||
if (net->command)
|
||||
{
|
||||
/* concat extra commands with a \n separator */
|
||||
tmp = net->command;
|
||||
net->command = malloc (strlen (tmp) + strlen (buf + 2) + 2);
|
||||
strcpy (net->command, tmp);
|
||||
strcat (net->command, "\n");
|
||||
strcat (net->command, buf + 2);
|
||||
free (tmp);
|
||||
} else
|
||||
net->command = strdup (buf + 2);
|
||||
break;
|
||||
case 'F':
|
||||
net->flags = atoi (buf + 2);
|
||||
break;
|
||||
case 'D':
|
||||
net->selected = atoi (buf + 2);
|
||||
case 'L':
|
||||
net->logintype = atoi (buf + 2);
|
||||
break;
|
||||
case 'E':
|
||||
net->encoding = strdup (buf + 2);
|
||||
break;
|
||||
case 'F':
|
||||
net->flags = atoi (buf + 2);
|
||||
break;
|
||||
case 'S': /* new server/hostname for this network */
|
||||
servlist_server_add (net, buf + 2);
|
||||
break;
|
||||
case 'C':
|
||||
servlist_command_add (net, buf + 2);
|
||||
break;
|
||||
case 'J':
|
||||
servlist_favchan_add (net, buf + 2);
|
||||
break;
|
||||
case 'D':
|
||||
net->selected = atoi (buf + 2);
|
||||
break;
|
||||
/* FIXME Migration code. In 2.9.5 the order was:
|
||||
*
|
||||
* P=serverpass, A=saslpass, B=nickservpass
|
||||
*
|
||||
* So if server password was unset, we can safely use SASL
|
||||
* password for our new universal password, or if that's also
|
||||
* unset, use NickServ password.
|
||||
*
|
||||
* Should be removed at some point.
|
||||
*/
|
||||
case 'A':
|
||||
if (!net->pass)
|
||||
{
|
||||
net->pass = strdup (buf + 2);
|
||||
if (!net->logintype)
|
||||
{
|
||||
net->logintype = LOGIN_SASL;
|
||||
}
|
||||
}
|
||||
case 'B':
|
||||
net->nickserv = strdup (buf + 2);
|
||||
break;
|
||||
case 'T':
|
||||
net->nstype = atoi (buf + 2);
|
||||
break;
|
||||
if (!net->pass)
|
||||
{
|
||||
net->pass = strdup (buf + 2);
|
||||
if (!net->logintype)
|
||||
{
|
||||
net->logintype = LOGIN_NICKSERV;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (buf[0] == 'N')
|
||||
@ -1187,13 +1366,6 @@ servlist_check_encoding (char *charset)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static int
|
||||
servlist_write_ccmd (char *str, void *fp)
|
||||
{
|
||||
return fprintf (fp, "C=%s\n", (str[0] == '/') ? str + 1 : str);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
servlist_save (void)
|
||||
{
|
||||
@ -1201,8 +1373,12 @@ servlist_save (void)
|
||||
char *buf;
|
||||
ircnet *net;
|
||||
ircserver *serv;
|
||||
commandentry *cmd;
|
||||
favchannel *favchan;
|
||||
GSList *list;
|
||||
GSList *hlist;
|
||||
GSList *netlist;
|
||||
GSList *cmdlist;
|
||||
GSList *favlist;
|
||||
#ifndef WIN32
|
||||
int first = FALSE;
|
||||
|
||||
@ -1244,26 +1420,8 @@ servlist_save (void)
|
||||
fprintf (fp, "R=%s\n", net->real);
|
||||
if (net->pass)
|
||||
fprintf (fp, "P=%s\n", net->pass);
|
||||
if (net->saslpass)
|
||||
fprintf (fp, "A=%s\n", net->saslpass);
|
||||
if (net->autojoin)
|
||||
fprintf (fp, "J=%s\n", net->autojoin);
|
||||
if (net->nickserv)
|
||||
fprintf (fp, "B=%s\n", net->nickserv);
|
||||
if (net->nstype)
|
||||
{
|
||||
if (net->nstype == -1) /* gtk_combo_box_get_active() returns -1 for invalid indices */
|
||||
{
|
||||
net->nstype = 0; /* avoid further crashes for the current session */
|
||||
buf = g_strdup_printf (_("Warning: invalid NickServ type. Falling back to default type for network %s."), net->name);
|
||||
fe_message (buf, FE_MSG_WARN);
|
||||
g_free (buf);
|
||||
}
|
||||
else /* the selection was fine, save it */
|
||||
{
|
||||
fprintf (fp, "T=%d\n", net->nstype);
|
||||
}
|
||||
}
|
||||
if (net->logintype)
|
||||
fprintf (fp, "L=%d\n", net->logintype);
|
||||
if (net->encoding && g_ascii_strcasecmp (net->encoding, "System") &&
|
||||
g_ascii_strcasecmp (net->encoding, "System default"))
|
||||
{
|
||||
@ -1277,17 +1435,39 @@ servlist_save (void)
|
||||
}
|
||||
}
|
||||
|
||||
if (net->command)
|
||||
token_foreach (net->command, '\n', servlist_write_ccmd, fp);
|
||||
|
||||
fprintf (fp, "F=%d\nD=%d\n", net->flags, net->selected);
|
||||
|
||||
hlist = net->servlist;
|
||||
while (hlist)
|
||||
netlist = net->servlist;
|
||||
while (netlist)
|
||||
{
|
||||
serv = hlist->data;
|
||||
serv = netlist->data;
|
||||
fprintf (fp, "S=%s\n", serv->hostname);
|
||||
hlist = hlist->next;
|
||||
netlist = netlist->next;
|
||||
}
|
||||
|
||||
cmdlist = net->commandlist;
|
||||
while (cmdlist)
|
||||
{
|
||||
cmd = cmdlist->data;
|
||||
fprintf (fp, "C=%s\n", cmd->command);
|
||||
cmdlist = cmdlist->next;
|
||||
}
|
||||
|
||||
favlist = net->favchanlist;
|
||||
while (favlist)
|
||||
{
|
||||
favchan = favlist->data;
|
||||
|
||||
if (favchan->key)
|
||||
{
|
||||
fprintf (fp, "J=%s,%s\n", favchan->name, favchan->key);
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf (fp, "J=%s\n", favchan->name);
|
||||
}
|
||||
|
||||
favlist = favlist->next;
|
||||
}
|
||||
|
||||
if (fprintf (fp, "\n") < 1)
|
||||
@ -1303,162 +1483,33 @@ servlist_save (void)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
joinlist_free1 (GSList *list)
|
||||
static int
|
||||
joinlist_find_chan (favchannel *curr_item, const char *channel)
|
||||
{
|
||||
GSList *head = list;
|
||||
|
||||
for (; list; list = list->next)
|
||||
g_free (list->data);
|
||||
g_slist_free (head);
|
||||
}
|
||||
|
||||
void
|
||||
joinlist_free (GSList *channels, GSList *keys)
|
||||
{
|
||||
joinlist_free1 (channels);
|
||||
joinlist_free1 (keys);
|
||||
if (!g_ascii_strcasecmp (curr_item->name, channel))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
gboolean
|
||||
joinlist_is_in_list (server *serv, char *channel)
|
||||
{
|
||||
GSList *channels, *keys;
|
||||
GSList *list;
|
||||
|
||||
if (!serv->network || !((ircnet *)serv->network)->autojoin)
|
||||
if (!serv->network || !((ircnet *)serv->network)->favchanlist)
|
||||
{
|
||||
return FALSE;
|
||||
|
||||
joinlist_split (((ircnet *)serv->network)->autojoin, &channels, &keys);
|
||||
|
||||
for (list = channels; list; list = list->next)
|
||||
{
|
||||
if (serv->p_cmp (list->data, channel) == 0)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
joinlist_free (channels, keys);
|
||||
|
||||
return FALSE;
|
||||
if (g_slist_find_custom (((ircnet *)serv->network)->favchanlist, channel, (GCompareFunc) joinlist_find_chan))
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
gchar *
|
||||
joinlist_merge (GSList *channels, GSList *keys)
|
||||
{
|
||||
GString *out = g_string_new (NULL);
|
||||
GSList *list;
|
||||
int i, j;
|
||||
|
||||
for (; channels; channels = channels->next)
|
||||
{
|
||||
g_string_append (out, channels->data);
|
||||
|
||||
if (channels->next)
|
||||
g_string_append_c (out, ',');
|
||||
}
|
||||
|
||||
/* count number of REAL keys */
|
||||
for (i = 0, list = keys; list; list = list->next)
|
||||
if (list->data)
|
||||
i++;
|
||||
|
||||
if (i > 0)
|
||||
{
|
||||
g_string_append_c (out, ' ');
|
||||
|
||||
for (j = 0; keys; keys = keys->next)
|
||||
{
|
||||
if (keys->data)
|
||||
{
|
||||
g_string_append (out, keys->data);
|
||||
j++;
|
||||
if (j == i)
|
||||
break;
|
||||
}
|
||||
|
||||
if (keys->next)
|
||||
g_string_append_c (out, ',');
|
||||
}
|
||||
}
|
||||
|
||||
return g_string_free (out, FALSE);
|
||||
}
|
||||
|
||||
void
|
||||
joinlist_split (char *autojoin, GSList **channels, GSList **keys)
|
||||
{
|
||||
char *parta, *partb;
|
||||
char *chan, *key;
|
||||
int len;
|
||||
|
||||
*channels = NULL;
|
||||
*keys = NULL;
|
||||
|
||||
/* after the first space, the keys begin */
|
||||
parta = autojoin;
|
||||
partb = strchr (autojoin, ' ');
|
||||
if (partb)
|
||||
partb++;
|
||||
|
||||
while (1)
|
||||
{
|
||||
chan = parta;
|
||||
key = partb;
|
||||
|
||||
if (1)
|
||||
{
|
||||
while (parta[0] != 0 && parta[0] != ',' && parta[0] != ' ')
|
||||
{
|
||||
parta++;
|
||||
}
|
||||
}
|
||||
|
||||
if (partb)
|
||||
{
|
||||
while (partb[0] != 0 && partb[0] != ',' && partb[0] != ' ')
|
||||
{
|
||||
partb++;
|
||||
}
|
||||
}
|
||||
|
||||
len = parta - chan;
|
||||
if (len < 1)
|
||||
break;
|
||||
*channels = g_slist_append (*channels, g_strndup (chan, len));
|
||||
|
||||
len = partb - key;
|
||||
*keys = g_slist_append (*keys, len ? g_strndup (key, len) : NULL);
|
||||
|
||||
if (parta[0] == ' ' || parta[0] == 0)
|
||||
break;
|
||||
parta++;
|
||||
|
||||
if (partb)
|
||||
{
|
||||
if (partb[0] == 0 || partb[0] == ' ')
|
||||
partb = NULL; /* no more keys, but maybe more channels? */
|
||||
else
|
||||
partb++;
|
||||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
GSList *lista, *listb;
|
||||
int i;
|
||||
|
||||
printf("-----\n");
|
||||
i = 0;
|
||||
lista = *channels;
|
||||
listb = *keys;
|
||||
while (lista)
|
||||
{
|
||||
printf("%d. |%s| |%s|\n", i, lista->data, listb->data);
|
||||
i++;
|
||||
lista = lista->next;
|
||||
listb = listb->next;
|
||||
}
|
||||
printf("-----\n\n");
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
@ -25,6 +25,17 @@ typedef struct ircserver
|
||||
char *hostname;
|
||||
} ircserver;
|
||||
|
||||
typedef struct commandentry
|
||||
{
|
||||
char *command;
|
||||
} commandentry;
|
||||
|
||||
typedef struct favchannel
|
||||
{
|
||||
char *name;
|
||||
char *key;
|
||||
} favchannel;
|
||||
|
||||
typedef struct ircnet
|
||||
{
|
||||
char *name;
|
||||
@ -33,14 +44,12 @@ typedef struct ircnet
|
||||
char *user;
|
||||
char *real;
|
||||
char *pass;
|
||||
char *saslpass;
|
||||
char *autojoin;
|
||||
char *command;
|
||||
char *nickserv;
|
||||
int nstype;
|
||||
int logintype;
|
||||
char *comment;
|
||||
char *encoding;
|
||||
GSList *servlist;
|
||||
GSList *commandlist;
|
||||
GSList *favchanlist;
|
||||
int selected;
|
||||
guint32 flags;
|
||||
} ircnet;
|
||||
@ -49,13 +58,24 @@ extern GSList *network_list;
|
||||
|
||||
#define FLAG_CYCLE 1
|
||||
#define FLAG_USE_GLOBAL 2
|
||||
#define FLAG_USE_SSL 4
|
||||
#define FLAG_USE_SSL 4
|
||||
#define FLAG_AUTO_CONNECT 8
|
||||
#define FLAG_USE_PROXY 16
|
||||
#define FLAG_ALLOW_INVALID 32
|
||||
#define FLAG_FAVORITE 64
|
||||
#define FLAG_COUNT 7
|
||||
|
||||
/* Login methods. Use server password by default - if we had a NickServ password, it'd be set to 2 already by servlist_load() */
|
||||
#define LOGIN_DEFAULT_REAL LOGIN_PASS /* this is to set the default login method for unknown servers */
|
||||
#define LOGIN_DEFAULT 0 /* this is for the login type dropdown, doesn't serve any other purpose */
|
||||
#define LOGIN_MSG_NICKSERV 1
|
||||
#define LOGIN_NICKSERV 2
|
||||
#define LOGIN_NS 3
|
||||
#define LOGIN_MSG_NS 4
|
||||
#define LOGIN_AUTH 5
|
||||
#define LOGIN_SASL 6
|
||||
#define LOGIN_PASS 7
|
||||
|
||||
/* DEFAULT_CHARSET is already defined in wingdi.h */
|
||||
#define IRC_DEFAULT_CHARSET "UTF-8 (Unicode)"
|
||||
|
||||
@ -74,13 +94,28 @@ void servlist_net_remove (ircnet *net);
|
||||
ircnet *servlist_net_find (char *name, int *pos, int (*cmpfunc) (const char *, const char *));
|
||||
ircnet *servlist_net_find_from_server (char *server_name);
|
||||
|
||||
void servlist_server_remove (ircnet *net, ircserver *serv);
|
||||
ircserver *servlist_server_add (ircnet *net, char *name);
|
||||
ircserver *servlist_server_find (ircnet *net, char *name, int *pos);
|
||||
commandentry *servlist_command_find (ircnet *net, char *cmd, int *pos);
|
||||
favchannel *servlist_favchan_find (ircnet *net, char *channel, int *pos);
|
||||
|
||||
ircserver *servlist_server_add (ircnet *net, char *name);
|
||||
commandentry *servlist_command_add (ircnet *net, char *command);
|
||||
void servlist_favchan_add (ircnet *net, char *channel);
|
||||
|
||||
void servlist_command_free (commandentry *entry);
|
||||
void servlist_favchan_free (favchannel *channel);
|
||||
|
||||
void servlist_server_remove (ircnet *net, ircserver *serv);
|
||||
void servlist_command_remove (ircnet *net, commandentry *entry);
|
||||
void servlist_favchan_remove (ircnet *net, favchannel *channel);
|
||||
|
||||
favchannel *servlist_favchan_copy (favchannel *fav);
|
||||
GSList *servlist_favchan_listadd (GSList *chanlist, char *channel, char *key);
|
||||
|
||||
void joinlist_split (char *autojoin, GSList **channels, GSList **keys);
|
||||
gboolean joinlist_is_in_list (server *serv, char *channel);
|
||||
void joinlist_free (GSList *channels, GSList *keys);
|
||||
gchar *joinlist_merge (GSList *channels, GSList *keys);
|
||||
|
||||
/* FIXME
|
||||
void joinlist_split (char *autojoin, GSList **channels, GSList **keys);
|
||||
void joinlist_free (GSList *channels, GSList *keys);
|
||||
*/
|
||||
#endif
|
||||
|
@ -1886,7 +1886,7 @@ int main (int argc, char *argv[])
|
||||
list = get_subdirs ("foo");
|
||||
display_list (list);
|
||||
#if GLIB_CHECK_VERSION(2,28,0)
|
||||
g_slist_free_full (list, (GFunc) g_free);
|
||||
g_slist_free_full (list, (GDestroyNotify) g_free);
|
||||
#else
|
||||
g_slist_foreach (list, (GFunc) g_free, NULL);
|
||||
g_slist_free (list);
|
||||
|
@ -685,14 +685,14 @@ dcc_detail_label (char *text, GtkWidget *box, int num)
|
||||
static void
|
||||
dcc_exp_cb (GtkWidget *exp, GtkWidget *box)
|
||||
{
|
||||
#if GTK_CHECK_VERSION(2,20,0)
|
||||
if (gtk_widget_get_visible (box))
|
||||
#else
|
||||
if (GTK_WIDGET_VISIBLE (box))
|
||||
#endif
|
||||
{
|
||||
gtk_widget_hide (box);
|
||||
}
|
||||
else
|
||||
{
|
||||
gtk_widget_show (box);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -897,15 +897,15 @@ fe_gui_info (session *sess, int info_type)
|
||||
switch (info_type)
|
||||
{
|
||||
case 0: /* window status */
|
||||
#if GTK_CHECK_VERSION(2,20,0)
|
||||
if (!gtk_widget_get_visible (GTK_WIDGET (sess->gui->window)))
|
||||
#else
|
||||
if (!GTK_WIDGET_VISIBLE (GTK_WIDGET (sess->gui->window)))
|
||||
#endif
|
||||
{
|
||||
return 2; /* hidden (iconified or systray) */
|
||||
}
|
||||
|
||||
if (gtk_window_is_active (GTK_WINDOW (sess->gui->window)))
|
||||
{
|
||||
return 1; /* active/focused */
|
||||
}
|
||||
|
||||
return 0; /* normal (no keyboard focus or behind a window) */
|
||||
}
|
||||
@ -920,11 +920,7 @@ fe_gui_info_ptr (session *sess, int info_type)
|
||||
{
|
||||
case 0: /* native window pointer (for plugins) */
|
||||
#ifdef WIN32
|
||||
#if GTK_CHECK_VERSION(2,24,8)
|
||||
return gdk_win32_window_get_impl_hwnd (sess->gui->window->window);
|
||||
#else
|
||||
return GDK_WINDOW_HWND (sess->gui->window->window);
|
||||
#endif
|
||||
#else
|
||||
return sess->gui->window;
|
||||
#endif
|
||||
|
@ -1637,10 +1637,6 @@ key_action_tab_comp (GtkWidget *t, GdkEventKey *entry, char *d1, char *d2,
|
||||
strncat (buf, result, COMP_BUF - prefix_len);
|
||||
cursor_pos = strlen (buf);
|
||||
g_free(result);
|
||||
#if !GLIB_CHECK_VERSION(2,4,0)
|
||||
g_utf8_validate (buf, -1, (const gchar **)&result);
|
||||
(*result) = 0;
|
||||
#endif
|
||||
if (postfix)
|
||||
{
|
||||
strcat (buf, " ");
|
||||
|
@ -1048,9 +1048,13 @@ menu_addfavoritemenu (server *serv, GtkWidget *menu, char *channel)
|
||||
}
|
||||
|
||||
if (joinlist_is_in_list (serv, channel))
|
||||
{
|
||||
mg_create_icon_item (_("_Remove from Favorites"), GTK_STOCK_REMOVE, menu, menu_delfav_cb, serv);
|
||||
}
|
||||
else
|
||||
{
|
||||
mg_create_icon_item (_("_Add to Favorites"), GTK_STOCK_ADD, menu, menu_addfav_cb, serv);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
@ -1729,11 +1733,7 @@ static gboolean
|
||||
menu_canacaccel (GtkWidget *widget, guint signal_id, gpointer user_data)
|
||||
{
|
||||
/* GTK2.2 behaviour */
|
||||
#if GTK_CHECK_VERSION(2,20,0)
|
||||
return gtk_widget_is_sensitive (widget);
|
||||
#else
|
||||
return GTK_WIDGET_IS_SENSITIVE (widget);
|
||||
#endif
|
||||
}
|
||||
|
||||
/* === STUFF FOR /MENU === */
|
||||
|
@ -414,11 +414,7 @@ tray_toggle_visibility (gboolean force_hide)
|
||||
if (!win)
|
||||
return FALSE;
|
||||
|
||||
#if GTK_CHECK_VERSION(2,20,0)
|
||||
if (force_hide || gtk_widget_get_visible (GTK_WIDGET (win)))
|
||||
#else
|
||||
if (force_hide || GTK_WIDGET_VISIBLE (win))
|
||||
#endif
|
||||
{
|
||||
if (prefs.hex_gui_tray_away)
|
||||
hexchat_command (ph, "ALLSERV AWAY");
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -954,7 +954,6 @@ enchant_has_lang(const gchar *lang, GSList *langs) {
|
||||
void
|
||||
sexy_spell_entry_activate_default_languages(SexySpellEntry *entry)
|
||||
{
|
||||
#if GLIB_CHECK_VERSION (2, 6, 0)
|
||||
/*const gchar* const *langs;
|
||||
int i;
|
||||
gchar *lastprefix = NULL;*/
|
||||
@ -1003,26 +1002,6 @@ sexy_spell_entry_activate_default_languages(SexySpellEntry *entry)
|
||||
/* If we don't have any languages activated, use "en" */
|
||||
if (entry->priv->dict_list == NULL)
|
||||
sexy_spell_entry_activate_language_internal(entry, "en", NULL);
|
||||
#else
|
||||
gchar *lang;
|
||||
|
||||
if (!have_enchant)
|
||||
return;
|
||||
|
||||
lang = (gchar *) g_getenv("LANG");
|
||||
|
||||
if (lang != NULL) {
|
||||
if (g_ascii_strncasecmp(lang, "C", 1) == 0)
|
||||
lang = NULL;
|
||||
else if (lang[0] == '\0')
|
||||
lang = NULL;
|
||||
}
|
||||
|
||||
if (lang == NULL)
|
||||
lang = "en";
|
||||
|
||||
sexy_spell_entry_activate_language_internal(entry, lang, NULL);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -1034,11 +1034,7 @@ gtk_xtext_realize (GtkWidget * widget)
|
||||
|
||||
gdk_window_set_user_data (widget->window, widget);
|
||||
|
||||
#if GTK_CHECK_VERSION(2,24,0)
|
||||
xtext->depth = gdk_window_get_visual (widget->window)->depth;
|
||||
#else
|
||||
xtext->depth = gdk_drawable_get_visual (widget->window)->depth;
|
||||
#endif
|
||||
|
||||
val.subwindow_mode = GDK_INCLUDE_INFERIORS;
|
||||
val.graphics_exposures = 0;
|
||||
|
Loading…
Reference in New Issue
Block a user