]> jfr.im git - solanum.git/blame - modules/m_topic.c
Revert "LIST: since we now have channel::strip_topic_colors, don't unconditionally...
[solanum.git] / modules / m_topic.c
CommitLineData
212380e3
AC
1/*
2 * ircd-ratbox: A slightly useful ircd.
3 * m_topic.c: Sets a channel topic.
4 *
5 * Copyright (C) 1990 Jarkko Oikarinen and University of Oulu, Co Center
6 * Copyright (C) 1996-2002 Hybrid Development Team
7 * Copyright (C) 2002-2005 ircd-ratbox development team
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
22 * USA
23 *
24 * $Id: m_topic.c 254 2005-09-21 23:35:12Z nenolod $
25 */
26
27#include "stdinc.h"
212380e3
AC
28#include "channel.h"
29#include "client.h"
30#include "hash.h"
4562c604 31#include "match.h"
212380e3
AC
32#include "ircd.h"
33#include "numeric.h"
34#include "send.h"
41615da9 35#include "s_newconf.h"
212380e3
AC
36#include "s_conf.h"
37#include "s_serv.h"
38#include "msg.h"
39#include "parse.h"
40#include "modules.h"
41#include "packet.h"
717238d2 42#include "tgchange.h"
77d3d2db 43#include "logger.h"
212380e3
AC
44
45static int m_topic(struct Client *, struct Client *, int, const char **);
46static int ms_topic(struct Client *, struct Client *, int, const char **);
47
48struct Message topic_msgtab = {
49 "TOPIC", 0, 0, 0, MFLG_SLOW,
50 {mg_unreg, {m_topic, 2}, {m_topic, 2}, {ms_topic, 5}, mg_ignore, {m_topic, 2}}
51};
52
53mapi_clist_av1 topic_clist[] = { &topic_msgtab, NULL };
54DECLARE_MODULE_AV1(topic, NULL, NULL, topic_clist, NULL, NULL, "$Revision: 254 $");
55
56/*
57 * m_topic
212380e3
AC
58 * parv[1] = channel name
59 * parv[2] = new topic, if setting topic
60 */
61static int
62m_topic(struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
63{
64 struct Channel *chptr = NULL;
65 struct membership *msptr;
66 char *p = NULL;
41615da9
JT
67 const char *name;
68 int operspy = 0;
212380e3
AC
69
70 if((p = strchr(parv[1], ',')))
71 *p = '\0';
72
41615da9
JT
73 name = parv[1];
74
75 if(IsOperSpy(source_p) && parv[1][0] == '!')
76 {
77 name++;
78 operspy = 1;
79
80 if(EmptyString(name))
81 {
82 sendto_one(source_p, form_str(ERR_NEEDMOREPARAMS),
83 me.name, source_p->name, "TOPIC");
84 return 0;
85 }
86 }
87
212380e3
AC
88 if(MyClient(source_p) && !IsFloodDone(source_p))
89 flood_endgrace(source_p);
90
41615da9 91 chptr = find_channel(name);
212380e3
AC
92
93 if(chptr == NULL)
94 {
95 sendto_one_numeric(source_p, ERR_NOSUCHCHANNEL,
41615da9 96 form_str(ERR_NOSUCHCHANNEL), name);
212380e3
AC
97 return 0;
98 }
99
100 /* setting topic */
101 if(parc > 2)
102 {
103 msptr = find_channel_membership(chptr, source_p);
104
105 if(msptr == NULL)
106 {
107 sendto_one_numeric(source_p, ERR_NOTONCHANNEL,
41615da9 108 form_str(ERR_NOTONCHANNEL), name);
212380e3
AC
109 return 0;
110 }
111
717238d2
JT
112 if(MyClient(source_p) && !is_chanop_voiced(msptr) &&
113 !IsOper(source_p) &&
114 !add_channel_target(source_p, chptr))
115 {
116 sendto_one(source_p, form_str(ERR_TARGCHANGE),
117 me.name, source_p->name, chptr->chname);
118 return 0;
119 }
120
406478d2 121 if(((chptr->mode.mode & MODE_TOPICLIMIT) == 0 ||
b870a5f8 122 get_channel_access(source_p, msptr, MODE_ADD, NULL) >= CHFL_CHANOP) &&
406478d2
JT
123 (!MyClient(source_p) ||
124 can_send(chptr, source_p, msptr)))
212380e3
AC
125 {
126 char topic_info[USERHOST_REPLYLEN];
7cdb0a09 127 rb_sprintf(topic_info, "%s!%s@%s",
212380e3 128 source_p->name, source_p->username, source_p->host);
e3354945 129 set_channel_topic(chptr, parv[2], topic_info, rb_current_time());
212380e3
AC
130
131 sendto_server(client_p, chptr, CAP_TS6, NOCAPS,
132 ":%s TOPIC %s :%s",
133 use_id(source_p), chptr->chname,
134 chptr->topic == NULL ? "" : chptr->topic);
212380e3
AC
135 sendto_channel_local(ALL_MEMBERS,
136 chptr, ":%s!%s@%s TOPIC %s :%s",
137 source_p->name, source_p->username,
138 source_p->host, chptr->chname,
139 chptr->topic == NULL ? "" : chptr->topic);
140 }
141 else
142 sendto_one(source_p, form_str(ERR_CHANOPRIVSNEEDED),
631b4a54
JT
143 get_id(&me, source_p),
144 get_id(source_p, source_p), name);
212380e3
AC
145 }
146 else if(MyClient(source_p))
147 {
41615da9
JT
148 if(operspy)
149 report_operspy(source_p, "TOPIC", chptr->chname);
150 if(!IsMember(source_p, chptr) && SecretChannel(chptr) &&
151 !operspy)
212380e3
AC
152 {
153 sendto_one_numeric(source_p, ERR_NOTONCHANNEL,
41615da9 154 form_str(ERR_NOTONCHANNEL), name);
212380e3
AC
155 return 0;
156 }
157 if(chptr->topic == NULL)
158 sendto_one(source_p, form_str(RPL_NOTOPIC),
41615da9 159 me.name, source_p->name, name);
212380e3
AC
160 else
161 {
162 sendto_one(source_p, form_str(RPL_TOPIC),
163 me.name, source_p->name, chptr->chname, chptr->topic);
164
165 sendto_one(source_p, form_str(RPL_TOPICWHOTIME),
166 me.name, source_p->name, chptr->chname,
0cce01d3
JT
167 chptr->topic_info,
168 (unsigned long)chptr->topic_time);
212380e3
AC
169 }
170 }
171
172 return 0;
173}
174
175/*
176 * ms_topic
212380e3
AC
177 * parv[1] = channel name
178 * parv[2] = topic_info
179 * parv[3] = topic_info time
180 * parv[4] = new channel topic
181 *
182 * Let servers always set a topic
183 */
184static int
185ms_topic(struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
186{
187 struct Channel *chptr = NULL;
188
0941f28e
JT
189 if((chptr = find_channel(parv[1])) == NULL)
190 return 0;
212380e3 191
0941f28e 192 set_channel_topic(chptr, parv[4], parv[2], atoi(parv[3]));
212380e3 193
0941f28e 194 sendto_channel_local(ALL_MEMBERS, chptr, ":%s TOPIC %s :%s",
55abcbb2 195 source_p->name, parv[1],
0941f28e 196 chptr->topic == NULL ? "" : chptr->topic);
212380e3
AC
197
198 return 0;
199}