[ekg2-commit] r4036 - trunk/plugins/irc: trunk/plugins/irc/irc.c trunk/plugins/irc/irc.h trunk/plugins/irc/session-pl.txt
SVN commit
svn w toxygen.net
Nie, 29 Cze 2008, 04:04:01 CEST
Author: wiechu
Date: 2008-06-29 04:03:59 +0200 (Sun, 29 Jun 2008)
New Revision: 4036
Modified:
trunk/plugins/irc/irc.c
trunk/plugins/irc/irc.h
trunk/plugins/irc/session-pl.txt
Log:
(draft) new irc session variable recode_list
Modified: trunk/plugins/irc/irc.c
===================================================================
--- trunk/plugins/irc/irc.c 2008-06-28 20:16:42 UTC (rev 4035)
+++ trunk/plugins/irc/irc.c 2008-06-29 02:03:59 UTC (rev 4036)
@@ -466,6 +466,136 @@
LIST_DESTROY(oldlist, list_irc_resolver_free);
}
+out_recodes_t *irc_find_out_recode(list_t rl, char *encname) {
+ out_recodes_t *recode;
+
+ if (!(encname && rl))
+ return NULL;
+
+ for ( ; rl; rl = rl->next) {
+ recode = (out_recodes_t *)(rl->data);
+ if ( recode->name && !xstrcasecmp(recode->name, encname) )
+ return recode;
+ }
+ return NULL;
+}
+
+recoded_channels_t *irc_find_recode_channel(list_t rcl, char *channame) {
+ recoded_channels_t *r_channel;
+
+ if (!(channame && rcl))
+ return NULL;
+
+ for ( ; rcl; rcl = rcl->next) {
+ r_channel = (recoded_channels_t *)(rcl->data);
+ if ( r_channel->name && !xstrcasecmp(r_channel->name, channame) )
+ return r_channel;
+ }
+ return NULL;
+}
+
+static char *irc_convert_out(irc_private_t *j, char *recipient, const char *line) {
+ char *recoded;
+ recoded_channels_t *r_channel;
+
+ if (!(j->recoded_channels)) {
+ /* channel/nick recode */
+ char *channame = (!xstrncasecmp(recipient, IRC4, 4)) ? recipient+4 : recipient;
+ if ((r_channel = irc_find_recode_channel(j->recoded_channels, channame))) {
+ if ((recoded = ekg_convert_string_p(line, r_channel->recode->conv_out)))
+ return recoded;
+ }
+ }
+
+ /* default recode */
+ if (j->conv_out == (void *) -1)
+ return NULL;
+
+ if (!(recoded = ekg_convert_string_p(line, j->conv_out)))
+ debug_error("[irc] ekg_convert_string_p() failed [%x] using not recoded text\n", j->conv_out);
+
+ return recoded;
+}
+
+static void irc_changed_recode_list(session_t *s, const char *var) {
+ const char *val;
+ irc_private_t *j;
+ char **list1, **list2, *nicks, *encoding;
+ void *conv_in, *conv_out;
+ int i,i2;
+ list_t rcl, rl;
+ out_recodes_t *recode;
+ recoded_channels_t *r_channel;
+
+ if (!s || !(j = s->priv))
+ return;
+
+ /* Clean old lists */
+ for (rcl = j->recoded_channels; rcl; ) {
+ r_channel = rcl->data;
+ rcl = rcl->next;
+ xfree(r_channel->name);
+ list_remove(&rcl, r_channel, 1);
+ }
+ for (rl = j->out_recodes; rl; ) {
+ recode = rl->data;
+ rl = rl->next;
+ xfree(recode->name);
+ ekg_convert_string_destroy(recode->conv_in);
+ ekg_convert_string_destroy(recode->conv_out);
+ list_remove(&rl, recode, 1);
+ }
+
+ if (!(val = session_get(s, var)) || !*val)
+ return;
+
+ /* Parse list */
+ // Syntax: encoding1:nick1,nick2,#chan1,nick3;encoding2:nick4,#chan5,chan6
+ list1 = array_make(val, ";", 0, 1, 0);
+ for (i=0; list1[i]; i++) {
+ if (!(nicks = xstrchr(list1[i], ':'))) {
+ debug_error("[irc] recode_list parse error: no colon. Skipped. '%s'\n", list1[i]);
+ continue;
+ }
+ *nicks++ = '\0';
+ encoding = list1[i];
+ if (!*nicks) {
+ debug_error("[irc] recode_list parse error: no nick or channel. Skipped. '%s:'\n", encoding);
+ continue;
+ }
+ if (!*encoding) {
+ debug_error("[irc] recode_list parse error: no encoding name. Skipped. ':%s'\n", nicks);
+ continue;
+ }
+
+ if (!(recode = irc_find_out_recode(j->out_recodes, encoding))) {
+ if (!(conv_in = ekg_convert_string_init(NULL, encoding, &(conv_out)))) {
+ debug_error("[irc] recode_list error: unknown encoding '%s'\n", encoding);
+ continue;
+ }
+ recode = xmalloc(sizeof(out_recodes_t));
+ recode->name = xstrdup(encoding);
+ recode->conv_in = conv_in;
+ recode->conv_out = conv_out;
+ list_add(&(j->out_recodes), recode);
+ }
+
+ list2 = array_make(nicks, ",", 0, 1, 0);
+ for(i2=0; list2[i2]; i2++) {
+ if ((r_channel = irc_find_recode_channel(j->recoded_channels, list2[i2]))) {
+ debug_error("[irc] recode_list. Duplicated channel/nick '%s'. Skipped.'\n", list2[i2]);
+ continue;
+ }
+ r_channel = xmalloc(sizeof(recoded_channels_t));
+ r_channel->name = xstrdup(list2[i2]);
+ r_channel->recode = recode;
+ list_add(&(j->recoded_channels), r_channel);
+ }
+ xfree(list2);
+ }
+ array_free(list1);
+}
+
static void irc_changed_recode(session_t *s, const char *var) {
const char *val;
irc_private_t *j;
@@ -507,9 +637,8 @@
list_remove(&el, e, 1);
}
- if (!(val = session_get(s, var)) || !*val) {
+ if (!(val = session_get(s, var)) || !*val)
return;
- }
char **args;
args = array_make(val, ",", 0, 1, 0);
@@ -1050,14 +1179,8 @@
*
* wo: Yes! We should use uncoded message for proper encoding in logs.
*/
- if (j->conv_out != (void *) -1) {
- __msg = ekg_convert_string_p(mline[1], j->conv_out);
- if (!__msg)
- debug_error("[irc] ekg_convert_string_p() failed [%x] using not recoded text\n", j->conv_out);
- }
-
- if (!__msg)
+ if (!(__msg = irc_convert_out(j, uid, mline[1])))
__msg = xstrdup((const char *)mline[1]);
coloured = irc_ircoldcolstr_to_ekgcolstr(session, head, 1);
@@ -1657,7 +1780,7 @@
static COMMAND(irc_command_topic) {
irc_private_t *j = irc_private(session);
- char **mp, *chan, *newtop;
+ char **mp, *chan, *newtop, *recode;
if (!(chan=irc_getchan(session, params, name,
&mp, 0, IRC_GC_CHAN)))
@@ -1672,15 +1795,9 @@
else
newtop = saprintf("TOPIC %s\r\n", chan+4);
- if (j->conv_out != (void *) -1) {
- char *recode = ekg_convert_string_p(newtop, j->conv_out);
-
- if (!recode)
- debug_error("[irc] ekg_convert_string_p() failed [%x] using not recoded text\n", j->conv_out);
- else {
- xfree(newtop);
- newtop = recode;
- }
+ if ((recode = irc_convert_out(j, chan+4, newtop))) {
+ xfree(newtop);
+ newtop = recode;
}
watch_write(j->send_watch, newtop);
@@ -1959,14 +2076,7 @@
ischn = chantypes?!!xstrchr(chantypes, chan[4]):0;
- if (j->conv_out != (void *) -1) {
- str = ekg_convert_string_p(*mp, j->conv_out);
-
- if (!str)
- debug_error("[irc] ekg_convert_string_p() failed [%x] using not recoded text\n", j->conv_out);
- }
-
- if (!str)
+ if (!(str = irc_convert_out(j, chan+4, *mp)))
str = xstrdup(*mp);
watch_write(irc_private(session)->send_watch, "PRIVMSG %s :\01ACTION %s\01\r\n",
@@ -2219,6 +2329,7 @@
PLUGIN_VAR_ADD("password", VAR_STR, 0, 1, NULL),
PLUGIN_VAR_ADD("port", VAR_INT, "6667", 0, NULL),
PLUGIN_VAR_ADD("realname", VAR_STR, NULL, 0, NULL), /* value will be inited @ irc_plugin_init() [pwd_entry->pw_gecos] */
+ PLUGIN_VAR_ADD("recode_list", VAR_STR, NULL, 0, irc_changed_recode_list),
PLUGIN_VAR_ADD("recode_out_default_charset", VAR_STR, NULL, 0, irc_changed_recode), /* irssi-like-variable */
PLUGIN_VAR_ADD("server", VAR_STR, 0, 0, irc_changed_resolve),
Modified: trunk/plugins/irc/irc.h
===================================================================
--- trunk/plugins/irc/irc.h 2008-06-28 20:16:42 UTC (rev 4035)
+++ trunk/plugins/irc/irc.h 2008-06-29 02:03:59 UTC (rev 4036)
@@ -64,6 +64,8 @@
list_t awaylog;
list_t auto_guess_encoding;
+ list_t out_recodes;
+ list_t recoded_channels;
void *conv_in;
void *conv_out;
@@ -75,6 +77,19 @@
void *conv_out;
} conv_in_out_t;
+/* data for private->out_recodes */
+typedef struct {
+ char *name; /* encoding name */
+ void *conv_in;
+ void *conv_out;
+} out_recodes_t;
+
+/* data for private->recoded_channels */
+typedef struct {
+ char *name; /* channel or nick */
+ out_recodes_t *recode;
+} recoded_channels_t;
+
typedef struct _irc_awaylog_t {
char *channame; /* channel name, (null if priv) */
char *uid; /* nickname who wrote to us */
Modified: trunk/plugins/irc/session-pl.txt
===================================================================
--- trunk/plugins/irc/session-pl.txt 2008-06-28 20:16:42 UTC (rev 4035)
+++ trunk/plugins/irc/session-pl.txt 2008-06-29 02:03:59 UTC (rev 4036)
@@ -125,6 +125,13 @@
odpowiedzi na /whois], by zmiany realname odniosły skutek należy się
ponownie połączyć
+recode_list
+ typ: text
+ domyślna wartość: brak
+
+ Lista kodowań dla poszczególnych nicków lub/i kanałów
+ Syntax: encoding1:nick1,nick2,#chan1,nick3;encoding2:nick4,#chan5,chan6
+
server
typ: tekst
domyślna wartość: brak
Więcej informacji o liście dyskusyjnej ekg2-commit