ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/ircd-hybrid/trunk/modules/m_topic.c
(Generate patch)

Comparing:
ircd-hybrid-7.2/modules/m_topic.c (file contents), Revision 895 by michael, Fri Nov 2 11:15:22 2007 UTC vs.
ircd-hybrid/trunk/modules/m_topic.c (file contents), Revision 6759 by michael, Fri Nov 13 18:23:37 2015 UTC

# Line 1 | Line 1
1   /*
2 < *  ircd-hybrid: an advanced Internet Relay Chat Daemon(ircd).
3 < *  m_topic.c: Sets a channel topic.
2 > *  ircd-hybrid: an advanced, lightweight Internet Relay Chat Daemon (ircd)
3   *
4 < *  Copyright (C) 2002 by the past and present ircd coders, and others.
4 > *  Copyright (c) 1997-2015 ircd-hybrid development team
5   *
6   *  This program is free software; you can redistribute it and/or modify
7   *  it under the terms of the GNU General Public License as published by
# Line 16 | Line 15
15   *
16   *  You should have received a copy of the GNU General Public License
17   *  along with this program; if not, write to the Free Software
18 < *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307
18 > *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
19   *  USA
20 < *
21 < *  $Id$
20 > */
21 >
22 > /*! \file m_topic.c
23 > * \brief Includes required functions for processing the TOPIC command.
24 > * \version $Id$
25   */
26  
27   #include "stdinc.h"
28 < #include "tools.h"
27 < #include "handlers.h"
28 > #include "list.h"
29   #include "channel.h"
30   #include "channel_mode.h"
31   #include "client.h"
32 + #include "conf.h"
33   #include "hash.h"
34   #include "irc_string.h"
33 #include "sprintf_irc.h"
35   #include "ircd.h"
36   #include "numeric.h"
37   #include "send.h"
37 #include "s_conf.h"
38 #include "s_serv.h"
39 #include "msg.h"
38   #include "parse.h"
39   #include "modules.h"
40   #include "packet.h"
43 #include "common.h"
44
45 static void m_topic(struct Client *, struct Client *, int, char *[]);
41  
47 struct Message topic_msgtab = {
48  "TOPIC", 0, 0, 2, 0, MFLG_SLOW, 0,
49  {m_unregistered, m_topic, m_topic, m_ignore, m_topic, m_ignore}
50 };
42  
43 < #ifndef STATIC_MODULES
44 < void
45 < _modinit(void)
46 < {
47 <  mod_add_cmd(&topic_msgtab);
48 < }
49 <
50 < void
51 < _moddeinit(void)
52 < {
53 <  mod_del_cmd(&topic_msgtab);
63 < }
64 <
65 < const char *_version = "$Revision$";
66 < #endif
67 <
68 < /* m_topic()
69 < *  parv[0] = sender prefix
70 < *  parv[1] = channel name
71 < *  parv[2] = new topic, if setting topic
43 > /*! \brief TOPIC command handler
44 > *
45 > * \param source_p Pointer to allocated Client struct from which the message
46 > *                 originally comes from.  This can be a local or remote client.
47 > * \param parc     Integer holding the number of supplied arguments.
48 > * \param parv     Argument vector where parv[0] .. parv[parc-1] are non-NULL
49 > *                 pointers.
50 > * \note Valid arguments for this command are:
51 > *      - parv[0] = command
52 > *      - parv[1] = channel name
53 > *      - parv[2] = topic text, if setting topic
54   */
55 < static void
56 < m_topic(struct Client *client_p, struct Client *source_p,
75 <        int parc, char *parv[])
55 > static int
56 > m_topic(struct Client *source_p, int parc, char *parv[])
57   {
58    struct Channel *chptr = NULL;
78  const char *from, *to;
79
80  if (!MyClient(source_p) && IsCapable(source_p->from, CAP_TS6) && HasID(source_p))
81  {
82    from = me.id;
83    to = source_p->id;
84  }
85  else
86  {
87    from = me.name;
88    to = source_p->name;
89  }
59  
60    if (EmptyString(parv[1]))
61    {
62 <    sendto_one(source_p, form_str(ERR_NEEDMOREPARAMS),
63 <               from, to, "TOPIC");
95 <    return;
62 >    sendto_one_numeric(source_p, &me, ERR_NEEDMOREPARAMS, "TOPIC");
63 >    return 0;
64    }
65  
66 <  if (MyClient(source_p) && !IsFloodDone(source_p))
66 >  if (!IsFloodDone(source_p))
67      flood_endgrace(source_p);
68  
69    if ((chptr = hash_find_channel(parv[1])) == NULL)
70    {
71 <    sendto_one(source_p, form_str(ERR_NOSUCHCHANNEL),
72 <               from, to, parv[1]);
105 <    return;
71 >    sendto_one_numeric(source_p, &me, ERR_NOSUCHCHANNEL, parv[1]);
72 >    return 0;
73    }
74  
75    /* setting topic */
76    if (parc > 2)
77    {
78 <    struct Membership *ms;
78 >    const struct Membership *member = NULL;
79  
80 <    if ((ms = find_channel_link(source_p, chptr)) == NULL)
80 >    if ((member = find_channel_link(source_p, chptr)) == NULL)
81      {
82 <      sendto_one(source_p, form_str(ERR_NOTONCHANNEL), from,
83 <                 to, parv[1]);
117 <      return;
82 >      sendto_one_numeric(source_p, &me, ERR_NOTONCHANNEL, chptr->name);
83 >      return 0;
84      }
85  
86      if (!(chptr->mode.mode & MODE_TOPICLIMIT) ||
87 <        has_member_flags(ms, CHFL_CHANOP|CHFL_HALFOP))
87 >        has_member_flags(member, CHFL_CHANOP|CHFL_HALFOP))
88      {
89 <      char topic_info[USERHOST_REPLYLEN];
89 >      char topic_info[USERHOST_REPLYLEN];
90  
91 <      ircsprintf(topic_info, "%s!%s@%s", source_p->name,
92 <                 source_p->username, source_p->host);
93 <      set_channel_topic(chptr, parv[2], topic_info, CurrentTime);
94 <
95 <      sendto_server(client_p, chptr, CAP_TS6, NOCAPS,
96 <                    ":%s TOPIC %s :%s",
97 <                    ID(source_p), chptr->chname,
98 <                    chptr->topic == NULL ? "" : chptr->topic);
133 <      sendto_server(client_p, chptr, NOCAPS, CAP_TS6,
134 <                    ":%s TOPIC %s :%s",
135 <                    source_p->name, chptr->chname,
136 <                    chptr->topic == NULL ? "" : chptr->topic);
137 <      sendto_channel_local(ALL_MEMBERS, NO,
138 <                           chptr, ":%s!%s@%s TOPIC %s :%s",
91 >      snprintf(topic_info, sizeof(topic_info), "%s!%s@%s", source_p->name,
92 >               source_p->username, source_p->host);
93 >      channel_set_topic(chptr, parv[2], topic_info, CurrentTime, 1);
94 >
95 >      sendto_server(source_p, 0, 0, ":%s TOPIC %s :%s",
96 >                    source_p->id, chptr->name,
97 >                    chptr->topic);
98 >      sendto_channel_local(NULL, chptr, 0, 0, 0, ":%s!%s@%s TOPIC %s :%s",
99                             source_p->name,
100                             source_p->username,
101                             source_p->host,
102 <                           chptr->chname, chptr->topic == NULL ?
143 <                           "" : chptr->topic);
102 >                           chptr->name, chptr->topic);
103      }
104      else
105 <      sendto_one(source_p, form_str(ERR_CHANOPRIVSNEEDED),
147 <                 from, to, chptr->chname);
105 >      sendto_one_numeric(source_p, &me, ERR_CHANOPRIVSNEEDED, chptr->name);
106    }
107    else /* only asking for topic */
108    {
109      if (!SecretChannel(chptr) || IsMember(source_p, chptr))
110      {
111 <      if (chptr->topic == NULL)
112 <        sendto_one(source_p, form_str(RPL_NOTOPIC),
155 <                   from, to, chptr->chname);
111 >      if (chptr->topic[0] == '\0')
112 >        sendto_one_numeric(source_p, &me, RPL_NOTOPIC, chptr->name);
113        else
114        {
115 <        sendto_one(source_p, form_str(RPL_TOPIC),
116 <                   from, to,
117 <                   chptr->chname, chptr->topic);
118 <        sendto_one(source_p, form_str(RPL_TOPICWHOTIME),
119 <                   from, to, chptr->chname,
163 <                   chptr->topic_info,
164 <                   chptr->topic_time);
115 >        sendto_one_numeric(source_p, &me, RPL_TOPIC,
116 >                           chptr->name, chptr->topic);
117 >        sendto_one_numeric(source_p, &me, RPL_TOPICWHOTIME, chptr->name,
118 >                           chptr->topic_info,
119 >                           chptr->topic_time);
120        }
121      }
122      else
123 <      sendto_one(source_p, form_str(ERR_NOTONCHANNEL),
169 <                 from, to, chptr->chname);
123 >      sendto_one_numeric(source_p, &me, ERR_NOTONCHANNEL, chptr->name);
124    }
125 +
126 +  return 0;
127   }
128 +
129 +
130 + /*! \brief TOPIC command handler
131 + *
132 + * \param source_p Pointer to allocated Client struct from which the message
133 + *                 originally comes from.  This can be a local or remote client.
134 + * \param parc     Integer holding the number of supplied arguments.
135 + * \param parv     Argument vector where parv[0] .. parv[parc-1] are non-NULL
136 + *                 pointers.
137 + * \note Valid arguments for this command are:
138 + *      - parv[0] = command
139 + *      - parv[1] = channel name
140 + *      - parv[2] = topic text
141 + */
142 + static int
143 + ms_topic(struct Client *source_p, int parc, char *parv[])
144 + {
145 +  struct Channel *chptr = NULL;
146 +  char topic_info[USERHOST_REPLYLEN];
147 +
148 +  if (EmptyString(parv[1]))
149 +  {
150 +    sendto_one_numeric(source_p, &me, ERR_NEEDMOREPARAMS, "TOPIC");
151 +    return 0;
152 +  }
153 +
154 +  if ((chptr = hash_find_channel(parv[1])) == NULL)
155 +  {
156 +    sendto_one_numeric(source_p, &me, ERR_NOSUCHCHANNEL, parv[1]);
157 +    return 0;
158 +  }
159 +
160 +  if (!IsClient(source_p))
161 +    strlcpy(topic_info, source_p->name, sizeof(topic_info));
162 +  else
163 +    snprintf(topic_info, sizeof(topic_info), "%s!%s@%s", source_p->name,
164 +             source_p->username, source_p->host);
165 +  channel_set_topic(chptr, parv[2], topic_info, CurrentTime, 0);
166 +
167 +  sendto_server(source_p, 0, 0, ":%s TOPIC %s :%s",
168 +                source_p->id, chptr->name,
169 +                chptr->topic);
170 +
171 +  if (!IsClient(source_p))
172 +    sendto_channel_local(NULL, chptr, 0, 0, 0, ":%s TOPIC %s :%s",
173 +                         (IsHidden(source_p) || ConfigServerHide.hide_servers) ? me.name : source_p->name,
174 +                         chptr->name, chptr->topic);
175 +
176 +  else
177 +    sendto_channel_local(NULL, chptr, 0, 0, 0, ":%s!%s@%s TOPIC %s :%s",
178 +                         source_p->name,
179 +                         source_p->username,
180 +                         source_p->host,
181 +                         chptr->name, chptr->topic);
182 +  return 0;
183 + }
184 +
185 +
186 + static struct Message topic_msgtab =
187 + {
188 +  .cmd = "TOPIC",
189 +  .args_min = 2,
190 +  .args_max = MAXPARA,
191 +  .handlers[UNREGISTERED_HANDLER] = m_unregistered,
192 +  .handlers[CLIENT_HANDLER] = m_topic,
193 +  .handlers[SERVER_HANDLER] = ms_topic,
194 +  .handlers[ENCAP_HANDLER] = m_ignore,
195 +  .handlers[OPER_HANDLER] = m_topic
196 + };
197 +
198 + static void
199 + module_init(void)
200 + {
201 +  mod_add_cmd(&topic_msgtab);
202 + }
203 +
204 + static void
205 + module_exit(void)
206 + {
207 +  mod_del_cmd(&topic_msgtab);
208 + }
209 +
210 + struct module module_entry =
211 + {
212 +  .version = "$Revision$",
213 +  .modinit = module_init,
214 +  .modexit = module_exit,
215 + };

Diff Legend

Removed lines
+ Added lines
< Changed lines (old)
> Changed lines (new)