Now inbound_cap_ls() can enable extensions when a bouncer uses a namespace for the...
[rofl0r-ixchat.git] / src / common / ctcp.c
blobb07a9580e90d8f9c680cb4cd50e99417025ab170
1 /* X-Chat
2 * Copyright (C) 1998 Peter Zelezny.
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
19 #include <stdio.h>
20 #include <string.h>
21 #include <unistd.h>
22 #include <stdlib.h>
24 #include "xchat.h"
25 #include "cfgfiles.h"
26 #include "util.h"
27 #include "modes.h"
28 #include "outbound.h"
29 #include "ignore.h"
30 #include "inbound.h"
31 #include "dcc.h"
32 #include "text.h"
33 #include "ctcp.h"
34 #include "server.h"
35 #include "xchatc.h"
38 static void
39 ctcp_reply (session *sess, char *nick, char *word[], char *word_eol[],
40 char *conf)
42 char tbuf[4096]; /* can receive 2048 from IRC, so this is enough */
44 conf = strdup (conf);
45 /* process %C %B etc */
46 check_special_chars (conf, TRUE);
47 auto_insert (tbuf, sizeof (tbuf), conf, word, word_eol, "", "", word_eol[5],
48 server_get_network (sess->server, TRUE), "", "", nick);
49 free (conf);
50 handle_command (sess, tbuf, FALSE);
53 static int
54 ctcp_check (session *sess, char *nick, char *word[], char *word_eol[],
55 char *ctcp)
57 int ret = 0;
58 char *po;
59 struct popup *pop;
60 GSList *list = ctcp_list;
62 po = strchr (ctcp, '\001');
63 if (po)
64 *po = 0;
66 po = strchr (word_eol[5], '\001');
67 if (po)
68 *po = 0;
70 while (list)
72 pop = (struct popup *) list->data;
73 if (!strcasecmp (ctcp, pop->name))
75 ctcp_reply (sess, nick, word, word_eol, pop->cmd);
76 ret = 1;
78 list = list->next;
80 return ret;
83 void
84 ctcp_handle (session *sess, char *to, char *nick, char *ip,
85 char *msg, char *word[], char *word_eol[], int id)
87 char *po;
88 session *chansess;
89 server *serv = sess->server;
90 char outbuf[1024];
91 int ctcp_offset = 2;
93 if (serv->have_idmsg && (word[4][1] == '+' || word[4][1] == '-') )
94 ctcp_offset = 3;
96 /* consider DCC to be different from other CTCPs */
97 if (!strncasecmp (msg, "DCC", 3))
99 /* but still let CTCP replies override it */
100 if (!ctcp_check (sess, nick, word, word_eol, word[4] + ctcp_offset))
102 if (!ignore_check (word[1], IG_DCC))
103 handle_dcc (sess, nick, word, word_eol);
105 return;
108 /* consider ACTION to be different from other CTCPs. Check
109 ignore as if it was a PRIV/CHAN. */
110 if (!strncasecmp (msg, "ACTION ", 7))
112 if (is_channel (serv, to))
114 /* treat a channel action as a CHAN */
115 if (ignore_check (word[1], IG_CHAN))
116 return;
117 } else
119 /* treat a private action as a PRIV */
120 if (ignore_check (word[1], IG_PRIV))
121 return;
124 /* but still let CTCP replies override it */
125 if (ctcp_check (sess, nick, word, word_eol, word[4] + ctcp_offset))
126 goto generic;
128 inbound_action (sess, to, nick, ip, msg + 7, FALSE, id);
129 return;
132 if (ignore_check (word[1], IG_CTCP))
133 return;
135 if (!strcasecmp (msg, "VERSION") && !prefs.hidever)
137 serv->p_nctcp (serv, nick, "VERSION Purple IRC");
140 if (!ctcp_check (sess, nick, word, word_eol, word[4] + ctcp_offset))
142 if (!strncasecmp (msg, "SOUND", 5))
144 po = strchr (word[5], '\001');
145 if (po)
146 po[0] = 0;
148 if (is_channel (sess->server, to))
150 chansess = find_channel (sess->server, to);
151 if (!chansess)
152 chansess = sess;
154 EMIT_SIGNAL (XP_TE_CTCPSNDC, chansess, word[5],
155 nick, to, NULL, 0);
156 } else
158 EMIT_SIGNAL (XP_TE_CTCPSND, sess->server->front_session, word[5],
159 nick, NULL, NULL, 0);
162 /* don't let IRCers specify path */
163 if (strchr (word[5], '/') == NULL)
164 sound_play (word[5], TRUE);
165 return;
169 generic:
170 po = strchr (msg, '\001');
171 if (po)
172 po[0] = 0;
174 if (!is_channel (sess->server, to))
176 EMIT_SIGNAL (XP_TE_CTCPGEN, sess->server->front_session, msg, nick,
177 NULL, NULL, 0);
178 } else
180 chansess = find_channel (sess->server, to);
181 if (!chansess)
182 chansess = sess;
183 EMIT_SIGNAL (XP_TE_CTCPGENC, chansess, msg, nick, to, NULL, 0);