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/modules/m_topic.c (file contents), Revision 33 by knight, Sun Oct 2 20:50:00 2005 UTC vs.
ircd-hybrid/trunk/modules/m_topic.c (file contents), Revision 4565 by michael, Sun Aug 24 10:27:40 2014 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-2014 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 "hash.h"
33   #include "irc_string.h"
33 – #include "sprintf_irc.h"
34   #include "ircd.h"
35   #include "numeric.h"
36   #include "send.h"
37 – #include "s_conf.h"
38 – #include "s_serv.h"
39 – #include "msg.h"
37   #include "parse.h"
38   #include "modules.h"
39   #include "packet.h"
43 – #include "common.h"
44 –
45 – static void m_topic(struct Client *, struct Client *, int, char **);
46 – static void ms_topic(struct Client *, struct Client *, int, char **);
47 –
48 – struct Message topic_msgtab = {
49 –  "TOPIC", 0, 0, 2, 0, MFLG_SLOW, 0,
50 –  {m_unregistered, m_topic, ms_topic, m_ignore, m_topic, m_ignore}
51 – };
40  
53 – #ifndef STATIC_MODULES
54 – void
55 – _modinit(void)
56 – {
57 –  mod_add_cmd(&topic_msgtab);
58 – }
41  
42 < void
43 < _moddeinit(void)
44 < {
45 <  mod_del_cmd(&topic_msgtab);
46 < }
47 <
48 < const char *_version = "$Revision$";
49 < #endif
50 <
51 < /* m_topic()
52 < *  parv[0] = sender prefix
71 < *  parv[1] = channel name
72 < *  parv[2] = new topic, if setting topic
42 > /*! \brief TOPIC command handler
43 > *
44 > * \param source_p Pointer to allocated Client struct from which the message
45 > *                 originally comes from.  This can be a local or remote client.
46 > * \param parc     Integer holding the number of supplied arguments.
47 > * \param parv     Argument vector where parv[0] .. parv[parc-1] are non-NULL
48 > *                 pointers.
49 > * \note Valid arguments for this command are:
50 > *      - parv[0] = command
51 > *      - parv[1] = channel name
52 > *      - parv[2] = topic text, if setting topic
53   */
54 < static void
55 < m_topic(struct Client *client_p, struct Client *source_p,
76 <        int parc, char *parv[])
54 > static int
55 > m_topic(struct Client *source_p, int parc, char *parv[])
56   {
57    struct Channel *chptr = NULL;
79 –  char *p;
80 –  struct Membership *ms;
81 –  const char *from, *to;
58  
59 <  if (!MyClient(source_p) && IsCapable(source_p->from, CAP_TS6) && HasID(source_p))
84 <  {
85 <    from = me.id;
86 <    to = source_p->id;
87 <  }
88 <  else
59 >  if (EmptyString(parv[1]))
60    {
61 <    from = me.name;
62 <    to = source_p->name;
61 >    sendto_one_numeric(source_p, &me, ERR_NEEDMOREPARAMS, "TOPIC");
62 >    return 0;
63    }
64  
65 <  if ((p = strchr(parv[1], ',')) != NULL)
66 <    *p = '\0';
65 >  if (!IsFloodDone(source_p))
66 >    flood_endgrace(source_p);
67  
68 <  if (parv[1][0] == '\0')
68 >  if ((chptr = hash_find_channel(parv[1])) == NULL)
69    {
70 <    sendto_one(source_p, form_str(ERR_NEEDMOREPARAMS),
71 <               from, to, "TOPIC");
101 <    return;
70 >    sendto_one_numeric(source_p, &me, ERR_NOSUCHCHANNEL, parv[1]);
71 >    return 0;
72    }
73  
74 <  if (MyClient(source_p) && !IsFloodDone(source_p))
75 <    flood_endgrace(source_p);
106 <
107 <  if (IsChanPrefix(*parv[1]))
74 >  /* setting topic */
75 >  if (parc > 2)
76    {
77 <    if ((chptr = hash_find_channel(parv[1])) == NULL)
77 >    const struct Membership *ms = NULL;
78 >
79 >    if ((ms = find_channel_link(source_p, chptr)) == NULL)
80      {
81 <      /* if chptr isn't found locally, it =could= exist
82 <       * on the uplink. so forward reqeuest
113 <       */
114 <      if (!ServerInfo.hub && uplink && IsCapable(uplink, CAP_LL))
115 <      {
116 <        sendto_one(uplink, ":%s TOPIC %s %s",
117 <                   ID_or_name(source_p, uplink), chptr->chname,
118 <                   ((parc > 2) ? parv[2] : ""));
119 <        return;
120 <      }
121 <      else
122 <      {
123 <        sendto_one(source_p, form_str(ERR_NOSUCHCHANNEL),
124 <                   from, to, parv[1]);
125 <        return;
126 <      }
81 >      sendto_one_numeric(source_p, &me, ERR_NOTONCHANNEL, chptr->chname);
82 >      return 0;
83      }
84  
85 <    /* setting topic */
86 <    if (parc > 2)
85 >    if (!(chptr->mode.mode & MODE_TOPICLIMIT) ||
86 >        has_member_flags(ms, CHFL_CHANOP|CHFL_HALFOP))
87      {
88 <      if ((ms = find_channel_link(source_p, chptr)) == NULL)
89 <      {
90 <        sendto_one(source_p, form_str(ERR_NOTONCHANNEL), from,
91 <                   to, parv[1]);
92 <        return;
93 <      }
94 <      if ((chptr->mode.mode & MODE_TOPICLIMIT) == 0 ||
95 <          has_member_flags(ms, CHFL_CHANOP|CHFL_HALFOP))
96 <      {
97 <        char topic_info[USERHOST_REPLYLEN];
98 <        ircsprintf(topic_info, "%s!%s@%s",
99 <                   source_p->name, source_p->username, source_p->host);
100 <        set_channel_topic(chptr, parv[2], topic_info, CurrentTime);
101 <
102 <        sendto_server(client_p, NULL, chptr, CAP_TS6, NOCAPS, NOFLAGS,
147 <                      ":%s TOPIC %s :%s",
148 <                      ID(source_p), chptr->chname,
149 <                      chptr->topic == NULL ? "" : chptr->topic);
150 <        sendto_server(client_p, NULL, chptr, NOCAPS, CAP_TS6, NOFLAGS,
151 <                      ":%s TOPIC %s :%s",
152 <                      source_p->name, chptr->chname,
153 <                      chptr->topic == NULL ? "" : chptr->topic);
154 <        sendto_channel_local(ALL_MEMBERS, NO,
155 <                             chptr, ":%s!%s@%s TOPIC %s :%s",
156 <                             source_p->name,
157 <                             source_p->username,
158 <                             source_p->host,
159 <                             chptr->chname, chptr->topic == NULL ?
160 <                             "" : chptr->topic);
161 <      }
162 <      else
163 <        sendto_one(source_p, form_str(ERR_CHANOPRIVSNEEDED),
164 <                   from, to, chptr->chname);
88 >      char topic_info[USERHOST_REPLYLEN];
89 >
90 >      snprintf(topic_info, sizeof(topic_info), "%s!%s@%s", source_p->name,
91 >               source_p->username, source_p->host);
92 >      channel_set_topic(chptr, parv[2], topic_info, CurrentTime, 1);
93 >
94 >      sendto_server(source_p, NOCAPS, NOCAPS, ":%s TOPIC %s :%s",
95 >                    source_p->id, chptr->chname,
96 >                    chptr->topic);
97 >      sendto_channel_local(ALL_MEMBERS, 0,
98 >                           chptr, ":%s!%s@%s TOPIC %s :%s",
99 >                           source_p->name,
100 >                           source_p->username,
101 >                           source_p->host,
102 >                           chptr->chname, chptr->topic);
103      }
104 <    else /* only asking for topic */
104 >    else
105 >      sendto_one_numeric(source_p, &me, ERR_CHANOPRIVSNEEDED, chptr->chname);
106 >  }
107 >  else /* only asking for topic */
108 >  {
109 >    if (!SecretChannel(chptr) || IsMember(source_p, chptr))
110      {
111 <      if (!SecretChannel(chptr) || IsMember(source_p, chptr))
112 <      {
170 <        if (chptr->topic == NULL)
171 <          sendto_one(source_p, form_str(RPL_NOTOPIC),
172 <                     from, to, chptr->chname);
173 <        else
174 <        {
175 <          sendto_one(source_p, form_str(RPL_TOPIC),
176 <                     from, to,
177 <                     chptr->chname, chptr->topic);
178 <
179 <          /* client on LL needing the topic - if we have serverhide, say
180 <           * its the actual LL server that set the topic, not us the
181 <           * uplink -- fl_
182 <           */
183 <          if (ConfigServerHide.hide_servers && !MyClient(source_p)
184 <              && IsCapable(client_p, CAP_LL) && ServerInfo.hub)
185 <          {
186 <            sendto_one(source_p, form_str(RPL_TOPICWHOTIME),
187 <                       from, to, chptr->chname,
188 <                       client_p->name, chptr->topic_time);
189 <          }
190 <          else
191 <          {
192 <            sendto_one(source_p, form_str(RPL_TOPICWHOTIME),
193 <                       from, to, chptr->chname,
194 <                       chptr->topic_info,
195 <                       chptr->topic_time);
196 <          }
197 <        }
198 <      }
111 >      if (chptr->topic[0] == '\0')
112 >        sendto_one_numeric(source_p, &me, RPL_NOTOPIC, chptr->chname);
113        else
114        {
115 <        sendto_one(source_p, form_str(ERR_NOTONCHANNEL),
116 <                   from, to, chptr->chname);
117 <        return;
115 >        sendto_one_numeric(source_p, &me, RPL_TOPIC,
116 >                           chptr->chname, chptr->topic);
117 >        sendto_one_numeric(source_p, &me, RPL_TOPICWHOTIME, chptr->chname,
118 >                           chptr->topic_info,
119 >                           chptr->topic_time);
120        }
121      }
122 +    else
123 +      sendto_one_numeric(source_p, &me, ERR_NOTONCHANNEL, chptr->chname);
124    }
125 <  else
126 <  {
209 <    sendto_one(source_p, form_str(ERR_NOSUCHCHANNEL),
210 <               from, to, parv[1]);
211 <  }
125 >
126 >  return 0;
127   }
128  
129 < /*
130 < * ms_topic
216 < *      parv[0] = sender prefix
217 < *      parv[1] = channel name
218 < *      parv[2] = topic_info
219 < *      parv[3] = topic_info time
220 < *      parv[4] = new channel topic
129 >
130 > /*! \brief TOPIC command handler
131   *
132 < * Let servers always set a topic
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 void
143 < ms_topic(struct Client *client_p, struct Client *source_p,
226 <         int parc, char *parv[])
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 (!IsServer(source_p))
148 >  if (EmptyString(parv[1]))
149    {
150 <    m_topic(client_p, source_p, parc, parv);
151 <    return;
150 >    sendto_one_numeric(source_p, &me, ERR_NEEDMOREPARAMS, "TOPIC");
151 >    return 0;
152    }
153  
154 <  if (parc < 5)
237 <    return;
238 <
239 <  if (parv[1] && IsChanPrefix(*parv[1]))
154 >  if ((chptr = hash_find_channel(parv[1])) == NULL)
155    {
156 <    if ((chptr = hash_find_channel(parv[1])) == NULL)
157 <      return;
156 >    sendto_one_numeric(source_p, &me, ERR_NOSUCHCHANNEL, parv[1]);
157 >    return 0;
158 >  }
159  
160 <    set_channel_topic(chptr, parv[4], parv[2], atoi(parv[3]));
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, NOCAPS, NOCAPS, ":%s TOPIC %s :%s",
168 >                source_p->id, chptr->chname,
169 >                chptr->topic);
170 >
171 >  if (!IsClient(source_p))
172 >    sendto_channel_local(ALL_MEMBERS, 0, chptr, ":%s TOPIC %s :%s",
173 >                         source_p->name,
174 >                         chptr->chname, chptr->topic);
175  
176 <    if (ConfigServerHide.hide_servers)
177 <    {
178 <      sendto_channel_local(ALL_MEMBERS, NO,
179 <                           chptr, ":%s TOPIC %s :%s",
180 <                           me.name, chptr->chname,
181 <                           chptr->topic == NULL ? "" : chptr->topic);
176 >  else
177 >    sendto_channel_local(ALL_MEMBERS, 0, chptr, ":%s!%s@%s TOPIC %s :%s",
178 >                         source_p->name,
179 >                         source_p->username,
180 >                         source_p->host,
181 >                         chptr->chname, chptr->topic);
182 >  return 0;
183 > }
184  
185 <    }
186 <    else
187 <    {
188 <      sendto_channel_local(ALL_MEMBERS, NO,
189 <                           chptr, ":%s TOPIC %s :%s",
190 <                           source_p->name,
191 <                           chptr->chname, chptr->topic == NULL ? "" : chptr->topic);
192 <    }
193 <  }
185 >
186 > static struct Message topic_msgtab =
187 > {
188 >  "TOPIC", NULL, 0, 0, 2, MAXPARA, MFLG_SLOW, 0,
189 >  { m_unregistered, m_topic, ms_topic, m_ignore, m_topic, m_ignore }
190 > };
191 >
192 > static void
193 > module_init(void)
194 > {
195 >  mod_add_cmd(&topic_msgtab);
196   }
197 +
198 + static void
199 + module_exit(void)
200 + {
201 +  mod_del_cmd(&topic_msgtab);
202 + }
203 +
204 + struct module module_entry =
205 + {
206 +  .node    = { NULL, NULL, NULL },
207 +  .name    = NULL,
208 +  .version = "$Revision$",
209 +  .handle  = NULL,
210 +  .modinit = module_init,
211 +  .modexit = module_exit,
212 +  .flags   = 0
213 + };

Diff Legend

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