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

Comparing:
ircd-hybrid-7.3/modules/m_cap.c (file contents), Revision 1080 by michael, Wed Mar 10 23:09:36 2010 UTC vs.
ircd-hybrid/trunk/modules/m_cap.c (file contents), Revision 1832 by michael, Fri Apr 19 19:16:09 2013 UTC

# Line 2 | Line 2
2   *  ircd-hybrid: an advanced Internet Relay Chat Daemon(ircd).
3   *
4   *  Copyright (C) 2004 Kevin L. Mitchell <klmitch@mit.edu>
5 < *  Copyright (C) 2006 Hybrid Development Team
5 > *  Copyright (C) 2006-2012 Hybrid Development Team
6   *
7   *  This program is free software; you can redistribute it and/or modify
8   *  it under the terms of the GNU General Public License as published by
# Line 28 | Line 28
28   */
29  
30   #include "stdinc.h"
31 – #include "handlers.h"
31   #include "client.h"
32   #include "hash.h"
33   #include "ircd.h"
34   #include "numeric.h"
35 < #include "s_conf.h"
35 > #include "conf.h"
36   #include "s_user.h"
37   #include "s_serv.h"
38   #include "send.h"
40 – #include "msg.h"
39   #include "parse.h"
40   #include "modules.h"
43 – #include "common.h"
41   #include "packet.h"
42   #include "irc_string.h"
43  
47 – static void m_cap(struct Client *, struct Client *, int, char *[]);
48 –
49 – struct Message cap_msgtab = {
50 –  "CAP", 0, 0, 2, 0, MFLG_SLOW, 0,
51 –  { m_cap, m_cap, m_ignore, m_ignore, m_cap, m_ignore }
52 – };
53 –
54 – #ifndef STATIC_MODULES
55 – void
56 – _modinit(void)
57 – {
58 –  mod_add_cmd(&cap_msgtab);
59 – }
60 –
61 – void
62 – _moddeinit(void)
63 – {
64 –  mod_del_cmd(&cap_msgtab);
65 – }
66 –
67 – const char *_version = "$Revision$";
68 – #endif
44  
45   #define CAPFL_HIDDEN    0x0001  /**< Do not advertize this capability */
46   #define CAPFL_PROHIBIT  0x0002  /**< Client may not set this capability */
# Line 83 | Line 58 | static struct capabilities
58   } capab_list[] = {
59   #define _CAP(cap, flags, name)  \
60          { (cap), (flags), (name), sizeof(name) - 1 }
61 <  _CAP(CAP_MULTI_PREFIX, 0, "multi-prefix")
61 >  _CAP(CAP_MULTI_PREFIX, 0, "multi-prefix"),
62 >  _CAP(CAP_AWAY_NOTIFY, 0, "away-notify")
63   #undef _CAP
64   };
65  
# Line 164 | Line 140 | find_cap(const char **caplist_p, int *ne
140    return cap;    /* and return the capability (if any) */
141   }
142  
143 < /** Send a CAP \a subcmd list of capability changes to \a sptr.
143 > /** Send a CAP \a subcmd list of capability changes to \a source_p.
144   * If more than one line is necessary, each line before the last has
145   * an added "*" parameter before that line's capability list.
146 < * @param[in] sptr Client receiving capability list.
146 > * @param[in] source_p Client receiving capability list.
147   * @param[in] set Capabilities to show as set (with ack and sticky modifiers).
148   * @param[in] rem Capabalities to show as removed (with no other modifier).
149   * @param[in] subcmd Name of capability subcommand.
150   */
151   static int
152 < send_caplist(struct Client *sptr, unsigned int set,
152 > send_caplist(struct Client *source_p, unsigned int set,
153               unsigned int rem, const char *subcmd)
154   {
155    char capbuf[IRCD_BUFSIZE] = "", pfx[16];
# Line 182 | Line 158 | send_caplist(struct Client *sptr, unsign
158  
159    /* set up the buffer for the final LS message... */
160    clen = snprintf(cmdbuf, sizeof(capbuf), ":%s CAP %s %s ", me.name,
161 <                  sptr->name[0] ? sptr->name : "*", subcmd);
161 >                  source_p->name[0] ? source_p->name : "*", subcmd);
162  
163    for (i = 0, loc = 0; i < CAPAB_LIST_LEN; ++i)
164    {
# Line 221 | Line 197 | send_caplist(struct Client *sptr, unsign
197      if (sizeof(capbuf) < (clen + loc + len + 15))
198      {
199        /* would add too much; must flush */
200 <      sendto_one(sptr, "%s* :%s", cmdbuf, capbuf);
200 >      sendto_one(source_p, "%s* :%s", cmdbuf, capbuf);
201        capbuf[(loc = 0)] = '\0';    /* re-terminate the buffer... */
202      }
203  
# Line 229 | Line 205 | send_caplist(struct Client *sptr, unsign
205                      "%s%s", pfx, capab_list[i].name);
206    }
207  
208 <  sendto_one(sptr, "%s:%s", cmdbuf, capbuf);
208 >  sendto_one(source_p, "%s:%s", cmdbuf, capbuf);
209  
210    return 0;    /* convenience return */
211   }
212  
213   static int
214 < cap_ls(struct Client *sptr, const char *caplist)
214 > cap_ls(struct Client *source_p, const char *caplist)
215   {
216 <  if (IsUnknown(sptr)) /* registration hasn't completed; suspend it... */
217 <    sptr->localClient->registration |= REG_NEED_CAP;
216 >  if (IsUnknown(source_p)) /* registration hasn't completed; suspend it... */
217 >    source_p->localClient->registration |= REG_NEED_CAP;
218  
219 <  return send_caplist(sptr, 0, 0, "LS"); /* send list of capabilities */
219 >  return send_caplist(source_p, 0, 0, "LS"); /* send list of capabilities */
220   }
221  
222   static int
223 < cap_req(struct Client *sptr, const char *caplist)
223 > cap_req(struct Client *source_p, const char *caplist)
224   {
225    const char *cl = caplist;
226    struct capabilities *cap = NULL;
227    unsigned int set = 0, rem = 0;
228 <  unsigned int cs = sptr->localClient->cap_client; /* capability set */
229 <  unsigned int as = sptr->localClient->cap_active; /* active set */
228 >  unsigned int cs = source_p->localClient->cap_client; /* capability set */
229 >  unsigned int as = source_p->localClient->cap_active; /* active set */
230    int neg = 0;
231  
232 <  if (IsUnknown(sptr)) /* registration hasn't completed; suspend it... */
233 <    sptr->localClient->registration |= REG_NEED_CAP;
232 >  if (IsUnknown(source_p)) /* registration hasn't completed; suspend it... */
233 >    source_p->localClient->registration |= REG_NEED_CAP;
234  
235    while (cl) { /* walk through the capabilities list... */
236      if (!(cap = find_cap(&cl, &neg)) /* look up capability... */
237          || (!neg && (cap->flags & CAPFL_PROHIBIT)) /* is it prohibited? */
238          || (neg && (cap->flags & CAPFL_STICKY))) { /* is it sticky? */
239 <      sendto_one(sptr, ":%s CAP %s NAK :%s", me.name,
240 <                 sptr->name[0] ? sptr->name : "*", caplist);
239 >      sendto_one(source_p, ":%s CAP %s NAK :%s", me.name,
240 >                 source_p->name[0] ? source_p->name : "*", caplist);
241        return 0; /* can't complete requested op... */
242      }
243  
# Line 287 | Line 263 | cap_req(struct Client *sptr, const char
263    }
264  
265    /* Notify client of accepted changes and copy over results. */
266 <  send_caplist(sptr, set, rem, "ACK");
266 >  send_caplist(source_p, set, rem, "ACK");
267  
268 <  sptr->localClient->cap_client = cs;
269 <  sptr->localClient->cap_active = as;
268 >  source_p->localClient->cap_client = cs;
269 >  source_p->localClient->cap_active = as;
270  
271    return 0;
272   }
273  
274   static int
275 < cap_ack(struct Client *sptr, const char *caplist)
275 > cap_ack(struct Client *source_p, const char *caplist)
276   {
277    const char *cl = caplist;
278    struct capabilities *cap = NULL;
# Line 311 | Line 287 | cap_ack(struct Client *sptr, const char
287    {
288      /* walk through the capabilities list... */
289      if (!(cap = find_cap(&cl, &neg)) || /* look up capability... */
290 <        (neg ? (sptr->localClient->cap_active & cap->cap) :
291 <              !(sptr->localClient->cap_active & cap->cap))) /* uh... */
290 >        (neg ? (source_p->localClient->cap_active & cap->cap) :
291 >              !(source_p->localClient->cap_active & cap->cap))) /* uh... */
292        continue;
293  
294      if (neg)    /* set or clear the active capability... */
295 <      sptr->localClient->cap_active &= ~cap->cap;
295 >      source_p->localClient->cap_active &= ~cap->cap;
296      else
297 <      sptr->localClient->cap_active |=  cap->cap;
297 >      source_p->localClient->cap_active |=  cap->cap;
298    }
299  
300    return 0;
301   }
302  
303   static int
304 < cap_clear(struct Client *sptr, const char *caplist)
304 > cap_clear(struct Client *source_p, const char *caplist)
305   {
306    struct capabilities *cap = NULL;
307    unsigned int ii;
# Line 336 | Line 312 | cap_clear(struct Client *sptr, const cha
312      cap = &capab_list[ii];
313  
314      /* Only clear active non-sticky capabilities. */
315 <    if (!(sptr->localClient->cap_active & cap->cap) || (cap->flags & CAPFL_STICKY))
315 >    if (!(source_p->localClient->cap_active & cap->cap) || (cap->flags & CAPFL_STICKY))
316        continue;
317  
318      cleared |= cap->cap;
319 <    sptr->localClient->cap_client &= ~cap->cap;
319 >    source_p->localClient->cap_client &= ~cap->cap;
320  
321      if (!(cap->flags & CAPFL_PROTO))
322 <      sptr->localClient->cap_active &= ~cap->cap;
322 >      source_p->localClient->cap_active &= ~cap->cap;
323    }
324  
325 <  return send_caplist(sptr, 0, cleared, "ACK");
325 >  return send_caplist(source_p, 0, cleared, "ACK");
326   }
327  
328   static int
329 < cap_end(struct Client *sptr, const char *caplist)
329 > cap_end(struct Client *source_p, const char *caplist)
330   {
331 <  if (!IsUnknown(sptr))    /* registration has completed... */
331 >  if (!IsUnknown(source_p))    /* registration has completed... */
332      return 0;    /* so just ignore the message... */
333  
334    /* capability negotiation is now done... */
335 <  sptr->localClient->registration &= ~REG_NEED_CAP;
335 >  source_p->localClient->registration &= ~REG_NEED_CAP;
336  
337    /* if client is now done... */
338 <  if (!sptr->localClient->registration)
338 >  if (!source_p->localClient->registration)
339    {
340 <    register_local_user(sptr);
340 >    register_local_user(source_p);
341      return 0;
342    }
343  
# Line 369 | Line 345 | cap_end(struct Client *sptr, const char
345   }
346  
347   static int
348 < cap_list(struct Client *sptr, const char *caplist)
348 > cap_list(struct Client *source_p, const char *caplist)
349   {
350    /* Send the list of the client's capabilities */
351 <  return send_caplist(sptr, sptr->localClient->cap_client, 0, "LIST");
351 >  return send_caplist(source_p, source_p->localClient->cap_client, 0, "LIST");
352   }
353  
354   static struct subcmd
355   {
356    const char *cmd;
357 <  int (*proc)(struct Client *sptr, const char *caplist);
357 >  int (*proc)(struct Client *, const char *);
358   } cmdlist[] = {
359    { "ACK",   cap_ack   },
360    { "CLEAR", cap_clear },
# Line 396 | Line 372 | subcmd_search(const char *cmd, const str
372   }
373  
374   /** Handle a capability request or response from a client.
375 < * \param cptr Client that sent us the message.
376 < * \param sptr Original source of message.
377 < * \param parc Number of arguments.
378 < * \param parv Argument vector.
375 > * \param client_p Client that sent us the message.
376 > * \param source_p Original source of message.
377 > * \param parc     Number of arguments.
378 > * \param parv     Argument vector.
379   */
380   static void
381 < m_cap(struct Client *cptr, struct Client *sptr, int parc, char *parv[])
381 > m_cap(struct Client *client_p, struct Client *source_p, int parc, char *parv[])
382   {
383 <  char *subcmd = NULL, *caplist = NULL;
383 >  const char *subcmd = NULL, *caplist = NULL;
384    struct subcmd *cmd = NULL;
385  
386 <  if (parc < 2 || EmptyString(parv[1]))    /* a subcommand is required */
386 >  if (EmptyString(parv[1]))    /* a subcommand is required */
387      return;
388  
389    subcmd = parv[1];
# Line 420 | Line 396 | m_cap(struct Client *cptr, struct Client
396                        sizeof(cmdlist) / sizeof(struct subcmd),
397                        sizeof(struct subcmd), (bqcmp)subcmd_search)))
398    {
399 <    sendto_one(sptr, form_str(ERR_INVALIDCAPCMD),
400 <               me.name, sptr->name, subcmd);
399 >    sendto_one(source_p, ERR_INVALIDCAPCMD, me.name,
400 >               source_p->name[0] ? source_p->name : "*", subcmd);
401      return;
402    }
403  
404    /* then execute it... */
405    if (cmd->proc)
406 <    (cmd->proc)(sptr, caplist);
406 >    (cmd->proc)(source_p, caplist);
407   }
408 +
409 + static struct Message cap_msgtab = {
410 +  "CAP", 0, 0, 2, MAXPARA, MFLG_SLOW, 0,
411 +  { m_cap, m_cap, m_ignore, m_ignore, m_cap, m_ignore }
412 + };
413 +
414 + static void
415 + module_init(void)
416 + {
417 +  mod_add_cmd(&cap_msgtab);
418 + }
419 +
420 + static void
421 + module_exit(void)
422 + {
423 +  mod_del_cmd(&cap_msgtab);
424 + }
425 +
426 + struct module module_entry = {
427 +  .node    = { NULL, NULL, NULL },
428 +  .name    = NULL,
429 +  .version = "$Revision$",
430 +  .handle  = NULL,
431 +  .modinit = module_init,
432 +  .modexit = module_exit,
433 +  .flags   = 0
434 + };

Diff Legend

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