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

Comparing:
ircd-hybrid-8/modules/m_dline.c (file contents), Revision 1230 by michael, Thu Sep 22 19:41:19 2011 UTC vs.
ircd-hybrid/trunk/modules/m_dline.c (file contents), Revision 1793 by michael, Sun Mar 31 14:06:08 2013 UTC

# Line 26 | Line 26
26   #include "list.h"
27   #include "channel.h"
28   #include "client.h"
29 #include "common.h"
29   #include "irc_string.h"
30 < #include "sprintf_irc.h"
30 > #include "conf.h"
31   #include "ircd.h"
32   #include "hostmask.h"
33   #include "numeric.h"
34   #include "fdlist.h"
35   #include "s_bsd.h"
36 < #include "s_conf.h"
38 < #include "s_log.h"
36 > #include "log.h"
37   #include "s_misc.h"
38   #include "send.h"
39   #include "hash.h"
42 #include "handlers.h"
40   #include "s_serv.h"
44 #include "msg.h"
45 #include "s_gline.h"
41   #include "parse.h"
42   #include "modules.h"
43 + #include "conf_db.h"
44 + #include "memory.h"
45  
46  
50 static int remove_tdline_match(const char *);
51
47   /* apply_tdline()
48   *
49   * inputs       -
# Line 56 | Line 51 | static int remove_tdline_match(const cha
51   * side effects - tkline as given is placed
52   */
53   static void
54 < apply_tdline(struct Client *source_p, struct ConfItem *conf,
55 <             const char *current_date, int tkline_time)
54 > apply_dline(struct Client *source_p, struct MaskItem *conf,
55 >            time_t tkline_time)
56   {
57 <  struct AccessItem *aconf;
57 >  if (tkline_time)
58 >  {
59 >    conf->until = CurrentTime + tkline_time;
60 >    sendto_realops_flags(UMODE_ALL, L_ALL, SEND_NOTICE,
61 >                         "%s added temporary %d min. D-Line for [%s] [%s]",
62 >                         get_oper_name(source_p), tkline_time/60,
63 >                         conf->host, conf->reason);
64 >    sendto_one(source_p, ":%s NOTICE %s :Added temporary %d min. D-Line [%s]",
65 >               MyConnect(source_p) ? me.name : ID_or_name(&me, source_p->from),
66 >               source_p->name, tkline_time/60, conf->host);
67 >    ilog(LOG_TYPE_DLINE, "%s added temporary %d min. D-Line for [%s] [%s]",
68 >         get_oper_name(source_p), tkline_time/60, conf->host, conf->reason);
69 >  }
70 >  else
71 >  {
72 >    sendto_realops_flags(UMODE_ALL, L_ALL, SEND_NOTICE,
73 >                         "%s added D-Line for [%s] [%s]",
74 >                         get_oper_name(source_p), conf->host, conf->reason);
75 >    sendto_one(source_p, ":%s NOTICE %s :Added D-Line [%s]",
76 >               MyConnect(source_p) ? me.name : ID_or_name(&me, source_p->from),
77 >               source_p->name, conf->host);
78 >    ilog(LOG_TYPE_DLINE, "%s added D-Line for [%s] [%s]",
79 >         get_oper_name(source_p), conf->host, conf->reason);
80  
81 <  aconf = map_to_conf(conf);
65 <  aconf->hold = CurrentTime + tkline_time;
81 >  }
82  
83 <  add_temp_line(conf);
84 <  sendto_realops_flags(UMODE_ALL, L_ALL,
85 <                       "%s added temporary %d min. D-Line for [%s] [%s]",
70 <                       get_oper_name(source_p), tkline_time/60,
71 <                       aconf->host, aconf->reason);
72 <
73 <  sendto_one(source_p, ":%s NOTICE %s :Added temporary %d min. D-Line [%s]",
74 <             MyConnect(source_p) ? me.name : ID_or_name(&me, source_p->from),
75 <             source_p->name, tkline_time/60, aconf->host);
76 <  ilog(L_TRACE, "%s added temporary %d min. D-Line for [%s] [%s]",
77 <       source_p->name, tkline_time/60, aconf->host, aconf->reason);
78 <  log_oper_action(LOG_TEMP_DLINE_TYPE, source_p, "[%s@%s] [%s]\n",
79 <                  aconf->user, aconf->host, aconf->reason);
83 >  SetConfDatabase(conf);
84 >  conf->setat = CurrentTime;
85 >  add_conf_by_address(CONF_DLINE, conf);
86    rehashed_klines = 1;
87   }
88  
89 + /* static int remove_tdline_match(const char *host, const char *user)
90 + * Input: An ip to undline.
91 + * Output: returns YES on success, NO if no tdline removed.
92 + * Side effects: Any matching tdlines are removed.
93 + */
94 + static int
95 + remove_dline_match(const char *host)
96 + {
97 +  struct irc_ssaddr iphost, *piphost;
98 +  struct MaskItem *conf;
99 +  int t = 0;
100 +  int aftype = 0;
101 +
102 +  if ((t = parse_netmask(host, &iphost, NULL)) != HM_HOST)
103 +  {
104 + #ifdef IPV6
105 +    if (t == HM_IPV6)
106 +      aftype = AF_INET6;
107 +    else
108 + #endif
109 +      aftype = AF_INET;
110 +    piphost = &iphost;
111 +  }
112 +  else
113 +    piphost = NULL;
114 +
115 +  if ((conf = find_conf_by_address(host, piphost, CONF_DLINE | 1, aftype, NULL, NULL, 0)))
116 +  {
117 +    if (IsConfDatabase(conf))
118 +    {
119 +      delete_one_address_conf(host, conf);
120 +      return 1;
121 +    }
122 +  }
123 +
124 +  return 0;
125 + }
126 +
127   /* mo_dline()
128   *
129   * inputs       - pointer to server
# Line 94 | Line 138 | static void
138   mo_dline(struct Client *client_p, struct Client *source_p,
139           int parc, char *parv[])
140   {
141 <  char def_reason[] = "No reason";
142 <  char *dlhost, *oper_reason, *reason;
141 >  char def_reason[] = "<No reason specified>";
142 >  char *dlhost = NULL, *reason = NULL;
143 >  char *target_server = NULL;
144    const char *creason;
145    const struct Client *target_p = NULL;
146    struct irc_ssaddr daddr;
147 <  struct ConfItem *conf=NULL;
103 <  struct AccessItem *aconf=NULL;
147 >  struct MaskItem *conf=NULL;
148    time_t tkline_time=0;
149 <  int bits, t;
149 >  int bits = 0, aftype = 0, t = 0;
150    const char *current_date = NULL;
151    time_t cur_time;
152 <  char hostip[HOSTIPLEN];
152 >  char hostip[HOSTIPLEN + 1];
153    char buffer[IRCD_BUFSIZE];
154  
155 <  if (!HasOFlag(source_p, OPER_FLAG_K))
155 >  if (!HasOFlag(source_p, OPER_FLAG_DLINE))
156    {
157      sendto_one(source_p, form_str(ERR_NOPRIVS),
158 <               me.name, source_p->name, "kline");
158 >               me.name, source_p->name, "dline");
159      return;
160    }
161  
162    if (parse_aline("DLINE", source_p,  parc, parv, AWILD, &dlhost,
163 <                  NULL, &tkline_time, NULL, &reason) < 0)
163 >                  NULL, &tkline_time, &target_server, &reason) < 0)
164      return;
165  
166 +  if (target_server != NULL)
167 +  {
168 +    if (HasID(source_p))
169 +    {
170 +      sendto_server(NULL, CAP_DLN|CAP_TS6, NOCAPS,
171 +                    ":%s DLINE %s %lu %s :%s",
172 +                    source_p->id, target_server, (unsigned long)tkline_time,
173 +                    dlhost, reason);
174 +      sendto_server(NULL, CAP_DLN, CAP_TS6,
175 +                    ":%s DLINE %s %lu %s :%s",
176 +                    source_p->name, target_server, (unsigned long)tkline_time,
177 +                    dlhost, reason);
178 +    }
179 +    else
180 +      sendto_server(NULL, CAP_DLN, NOCAPS,
181 +                    ":%s DLINE %s %lu %s :%s",
182 +                    source_p->name, target_server, (unsigned long)tkline_time,
183 +                    dlhost, reason);
184 +
185 +    /* Allow ON to apply local kline as well if it matches */
186 +    if (match(target_server, me.name))
187 +      return;
188 +  }
189 +  else
190 +    cluster_a_line(source_p, "DLINE", CAP_DLN, SHARED_DLINE,
191 +                   "%d %s :%s", tkline_time, dlhost, reason);
192 +
193    if ((t = parse_netmask(dlhost, NULL, &bits)) == HM_HOST)
194    {
195      if ((target_p = find_chasing(client_p, source_p, dlhost, NULL)) == NULL)
# Line 158 | Line 229 | mo_dline(struct Client *client_p, struct
229  
230   #ifdef IPV6
231    if (t == HM_IPV6)
232 <    t = AF_INET6;
232 >    aftype = AF_INET6;
233    else
234   #endif
235 <    t = AF_INET;
235 >    aftype = AF_INET;
236  
237    parse_netmask(dlhost, &daddr, NULL);
238  
239 <  if ((aconf = find_dline_conf(&daddr, t)) != NULL)
239 >  if ((conf = find_dline_conf(&daddr, aftype)) != NULL)
240    {
241 <    creason = aconf->reason ? aconf->reason : def_reason;
242 <    if (IsConfExemptKline(aconf))
241 >    creason = conf->reason ? conf->reason : def_reason;
242 >    if (IsConfExemptKline(conf))
243        sendto_one(source_p,
244                   ":%s NOTICE %s :[%s] is (E)d-lined by [%s] - %s",
245 <                 me.name, source_p->name, dlhost, aconf->host, creason);
245 >                 me.name, source_p->name, dlhost, conf->host, creason);
246      else
247        sendto_one(source_p,
248                   ":%s NOTICE %s :[%s] already D-lined by [%s] - %s",
249 <                 me.name, source_p->name, dlhost, aconf->host, creason);
249 >                 me.name, source_p->name, dlhost, conf->host, creason);
250      return;
251    }
252  
253    cur_time = CurrentTime;
254    current_date = smalldate(cur_time);
255  
256 <  /* Look for an oper reason */
186 <  if ((oper_reason = strchr(reason, '|')) != NULL)
187 <    *oper_reason++ = '\0';
188 <
189 <  if (!valid_comment(source_p, reason, YES))
256 >  if (!valid_comment(source_p, reason, 1))
257      return;
258  
259 <  conf = make_conf_item(DLINE_TYPE);
260 <  aconf = map_to_conf(conf);
194 <  DupString(aconf->host, dlhost);
259 >  conf = conf_make(CONF_DLINE);
260 >  conf->host = xstrdup(dlhost);
261  
262    if (tkline_time != 0)
263 <  {
264 <    ircsprintf(buffer, "Temporary D-line %d min. - %s (%s)",
199 <               (int)(tkline_time/60), reason, current_date);
200 <    DupString(aconf->reason, buffer);
201 <    if (oper_reason != NULL)
202 <      DupString(aconf->oper_reason, oper_reason);
203 <    apply_tdline(source_p, conf, current_date, tkline_time);
204 <  }
263 >    snprintf(buffer, sizeof(buffer), "Temporary D-line %d min. - %s (%s)",
264 >             (int)(tkline_time/60), reason, current_date);
265    else
266 <  {
207 <    ircsprintf(buffer, "%s (%s)", reason, current_date);
208 <    DupString(aconf->reason, buffer);
209 <    if (oper_reason != NULL)
210 <      DupString(aconf->oper_reason, oper_reason);
211 <    add_conf_by_address(CONF_DLINE, aconf);
212 <    write_conf_line(source_p, conf, current_date, cur_time);
213 <  }
266 >    snprintf(buffer, sizeof(buffer), "%s (%s)", reason, current_date);
267  
268 +  conf->reason = xstrdup(buffer);
269 +  apply_dline(source_p, conf, tkline_time);
270    rehashed_klines = 1;
271   }
272  
273 < /* static int remove_tdline_match(const char *host, const char *user)
274 < * Input: An ip to undline.
275 < * Output: returns YES on success, NO if no tdline removed.
221 < * Side effects: Any matching tdlines are removed.
222 < */
223 < static int
224 < remove_tdline_match(const char *cidr)
273 > static void
274 > ms_dline(struct Client *client_p, struct Client *source_p,
275 >         int parc, char *parv[])
276   {
277 <  struct AccessItem *td_conf;
278 <  dlink_node *td_node;
279 <  struct irc_ssaddr addr, caddr;
280 <  int nm_t, cnm_t, bits, cbits;
281 <  nm_t = parse_netmask(cidr, &addr, &bits);
282 <
283 <  DLINK_FOREACH(td_node, temporary_dlines.head)
277 >  char def_reason[] = "<No reason specified>";
278 >  char *dlhost, *reason;
279 >  const char *creason;
280 >  const struct Client *target_p = NULL;
281 >  struct irc_ssaddr daddr;
282 >  struct MaskItem *conf=NULL;
283 >  time_t tkline_time=0;
284 >  int bits = 0, aftype = 0, t = 0;
285 >  const char *current_date = NULL;
286 >  time_t cur_time;
287 >  char hostip[HOSTIPLEN + 1];
288 >  char buffer[IRCD_BUFSIZE];
289 >
290 >  if (parc != 5 || EmptyString(parv[4]))
291 >    return;
292 >
293 >  /* parv[0]  parv[1]        parv[2]      parv[3]  parv[4] */
294 >  /* oper     target_server  tkline_time  host     reason  */
295 >  sendto_match_servs(source_p, parv[1], CAP_DLN,
296 >                     "DLINE %s %s %s :%s",
297 >                     parv[1], parv[2], parv[3], parv[4]);
298 >
299 >  if (match(parv[1], me.name))
300 >    return;
301 >
302 >  tkline_time = valid_tkline(parv[2], TK_SECONDS);
303 >  dlhost = parv[3];
304 >  reason = parv[4];
305 >
306 >  if (HasFlag(source_p, FLAGS_SERVICE) || find_matching_name_conf(CONF_ULINE, source_p->servptr->name,
307 >                              source_p->username, source_p->host,
308 >                              SHARED_DLINE))
309    {
310 <    td_conf = map_to_conf(td_node->data);
311 <    cnm_t   = parse_netmask(td_conf->host, &caddr, &cbits);
310 >    if (!IsClient(source_p))
311 >      return;
312 >    if ((t = parse_netmask(dlhost, NULL, &bits)) == HM_HOST)
313 >    {
314 >      if ((target_p = find_chasing(client_p, source_p, dlhost, NULL)) == NULL)
315 >        return;
316  
317 <    if (cnm_t != nm_t)
318 <      continue;
317 >      if (!MyConnect(target_p))
318 >      {
319 >        sendto_one(source_p,
320 >                   ":%s NOTICE %s :Can't DLINE nick on another server",
321 >                   me.name, source_p->name);
322 >        return;
323 >      }
324 >
325 >      if (IsExemptKline(target_p))
326 >      {
327 >        sendto_one(source_p,
328 >                   ":%s NOTICE %s :%s is E-lined", me.name,
329 >                   source_p->name, target_p->name);
330 >        return;
331 >      }
332 >
333 >      getnameinfo((struct sockaddr *)&target_p->localClient->ip,
334 >                  target_p->localClient->ip.ss_len, hostip,
335 >                  sizeof(hostip), NULL, 0, NI_NUMERICHOST);
336 >      dlhost = hostip;
337 >      t = parse_netmask(dlhost, NULL, &bits);
338 >      assert(t == HM_IPV4 || t == HM_IPV6);
339 >    }
340 >
341 >    if (bits < 8)
342 >    {
343 >      sendto_one(source_p,
344 >                 ":%s NOTICE %s :For safety, bitmasks less than 8 require conf access.",
345 >                 me.name, source_p->name);
346 >      return;
347 >    }
348  
240    if((nm_t==HM_HOST && !irccmp(td_conf->host, cidr)) ||
241       (nm_t==HM_IPV4 && bits==cbits && match_ipv4(&addr, &caddr, bits))
349   #ifdef IPV6
350 <       || (nm_t==HM_IPV6 && bits==cbits && match_ipv6(&addr, &caddr, bits))
350 >    if (t == HM_IPV6)
351 >      aftype= AF_INET6;
352 >    else
353   #endif
354 <      )
354 >      aftype = AF_INET;
355 >
356 >    parse_netmask(dlhost, &daddr, NULL);
357 >
358 >    if ((conf = find_dline_conf(&daddr, aftype)) != NULL)
359      {
360 <      dlinkDelete(td_node, &temporary_dlines);
361 <      delete_one_address_conf(td_conf->host, td_conf);
362 <      return 1;
360 >      creason = conf->reason ? conf->reason : def_reason;
361 >      if (IsConfExemptKline(conf))
362 >        sendto_one(source_p,
363 >                   ":%s NOTICE %s :[%s] is (E)d-lined by [%s] - %s",
364 >                   me.name, source_p->name, dlhost, conf->host, creason);
365 >      else
366 >        sendto_one(source_p,
367 >                   ":%s NOTICE %s :[%s] already D-lined by [%s] - %s",
368 >                   me.name, source_p->name, dlhost, conf->host, creason);
369 >      return;
370      }
251  }
371  
372 <  return 0;
372 >    cur_time = CurrentTime;
373 >    current_date = smalldate(cur_time);
374 >
375 >    if (!valid_comment(source_p, reason, 1))
376 >      return;
377 >
378 >    conf = conf_make(CONF_DLINE);
379 >    conf->host = xstrdup(dlhost);
380 >
381 >    if (tkline_time != 0)
382 >      snprintf(buffer, sizeof(buffer), "Temporary D-line %d min. - %s (%s)",
383 >               (int)(tkline_time/60), reason, current_date);
384 >    else
385 >      snprintf(buffer, sizeof(buffer), "%s (%s)", reason, current_date);
386 >
387 >    conf->reason = xstrdup(buffer);
388 >    apply_dline(source_p, conf, tkline_time);
389 >    rehashed_klines = 1;
390 >  }
391   }
392  
393   /*
# Line 266 | Line 403 | static void
403   mo_undline(struct Client *client_p, struct Client *source_p,
404             int parc, char *parv[])
405   {
406 <  const char *cidr = NULL;
406 >  char *addr = NULL, *user = NULL;
407 >  char *target_server = NULL;
408  
409 <  if (!HasOFlag(source_p, OPER_FLAG_UNKLINE))
409 >  if (!HasOFlag(source_p, OPER_FLAG_UNDLINE))
410    {
411      sendto_one(source_p, form_str(ERR_NOPRIVS),
412                 me.name, source_p->name, "undline");
413      return;
414    }
415  
416 <  cidr = parv[1];
279 <
280 <  if (remove_tdline_match(cidr))
416 >  if (parc < 2 || EmptyString(parv[1]))
417    {
418 <    sendto_one(source_p,
419 <              ":%s NOTICE %s :Un-Dlined [%s] from temporary D-Lines",
284 <              me.name, source_p->name, cidr);
285 <    sendto_realops_flags(UMODE_ALL, L_ALL,
286 <                         "%s has removed the temporary D-Line for: [%s]",
287 <                         get_oper_name(source_p), cidr);
288 <    ilog(L_NOTICE, "%s removed temporary D-Line for [%s]", source_p->name, cidr);
418 >    sendto_one(source_p, form_str(ERR_NEEDMOREPARAMS),
419 >               me.name, source_p->name, "UNDLINE");
420      return;
421    }
422  
423 <  if (remove_conf_line(DLINE_TYPE, source_p, cidr, NULL) > 0)
424 <  {
425 <    sendto_one(source_p, ":%s NOTICE %s :D-Line for [%s] is removed",
426 <               me.name, source_p->name, cidr);
427 <    sendto_realops_flags(UMODE_ALL, L_ALL,
428 <                         "%s has removed the D-Line for: [%s]",
429 <                         get_oper_name(source_p), cidr);
430 <    ilog(L_NOTICE, "%s removed D-Line for [%s]",
431 <         get_oper_name(source_p), cidr);
423 >  if (parse_aline("UNDLINE", source_p, parc, parv, 0, &user,
424 >                  &addr, NULL, &target_server, NULL) < 0)
425 >    return;
426 >
427 >  if (target_server != NULL)
428 >  {
429 >    sendto_match_servs(source_p, target_server, CAP_UNDLN,
430 >                       "UNDLINE %s %s", target_server, addr);
431 >
432 >    /* Allow ON to apply local unkline as well if it matches */
433 >    if (match(target_server, me.name))
434 >      return;
435 >  }
436 >  else
437 >    cluster_a_line(source_p, "UNDLINE", CAP_UNDLN, SHARED_UNDLINE,
438 >                   "%s", addr);
439 >
440 >  if (remove_dline_match(addr))
441 >  {
442 >    sendto_one(source_p,
443 >               ":%s NOTICE %s :D-Line for [%s] is removed",
444 >               me.name, source_p->name, addr);
445 >    sendto_realops_flags(UMODE_ALL, L_ALL, SEND_NOTICE,
446 >                         "%s has removed the D-Line for: [%s]",
447 >                         get_oper_name(source_p), addr);
448 >    ilog(LOG_TYPE_DLINE, "%s removed D-Line for [%s]",
449 >         get_oper_name(source_p), addr);
450    }
451    else
452      sendto_one(source_p, ":%s NOTICE %s :No D-Line for [%s] found",
453 <               me.name, source_p->name, cidr);
453 >               me.name, source_p->name, addr);
454 > }
455 >
456 > static void
457 > me_undline(struct Client *client_p, struct Client *source_p,
458 >           int parc, char *parv[])
459 > {
460 >  const char *addr = NULL;
461 >
462 >  if (parc != 3 || EmptyString(parv[2]))
463 >    return;
464 >
465 >  addr = parv[2];
466 >
467 >  if (!IsClient(source_p) || match(parv[1], me.name))
468 >    return;
469 >
470 >  if (HasFlag(source_p, FLAGS_SERVICE) || find_matching_name_conf(CONF_ULINE,
471 >                                   source_p->servptr->name,
472 >                                   source_p->username, source_p->host,
473 >                                   SHARED_UNDLINE))
474 >  {
475 >    if (remove_dline_match(addr))
476 >    {
477 >      sendto_one(source_p,
478 >                 ":%s NOTICE %s :D-Line for [%s] is removed",
479 >                 me.name, source_p->name, addr);
480 >      sendto_realops_flags(UMODE_ALL, L_ALL, SEND_NOTICE,
481 >                           "%s has removed the D-Line for: [%s]",
482 >                           get_oper_name(source_p), addr);
483 >      ilog(LOG_TYPE_DLINE, "%s removed temporary D-Line for [%s]",
484 >           get_oper_name(source_p), addr);
485 >    }
486 >    else
487 >      sendto_one(source_p, ":%s NOTICE %s :No D-Line for [%s] found",
488 >                 me.name, source_p->name, addr);
489 >  }
490 > }
491 >
492 > static void
493 > ms_undline(struct Client *client_p, struct Client *source_p,
494 >           int parc, char *parv[])
495 > {
496 >  if (parc != 3 || EmptyString(parv[2]))
497 >    return;
498 >
499 >  sendto_match_servs(source_p, parv[1], CAP_UNDLN,
500 >                     "UNDLINE %s %s",
501 >                     parv[1], parv[2]);
502 >
503 >  me_undline(client_p, source_p, parc, parv);
504   }
505  
506   static struct Message dline_msgtab = {
507    "DLINE", 0, 0, 2, MAXPARA, MFLG_SLOW, 0,
508 <   {m_unregistered, m_not_oper, rfc1459_command_send_error, m_ignore, mo_dline, m_ignore}
508 >   {m_unregistered, m_not_oper, ms_dline, m_ignore, mo_dline, m_ignore}
509   };
510  
511   static struct Message undline_msgtab = {
512    "UNDLINE", 0, 0, 2, MAXPARA, MFLG_SLOW, 0,
513 <   {m_unregistered, m_not_oper, rfc1459_command_send_error, m_ignore, mo_undline, m_ignore}
513 >   {m_unregistered, m_not_oper, ms_undline, m_ignore, mo_undline, m_ignore}
514   };
515  
516   static void
# Line 319 | Line 518 | module_init(void)
518   {
519    mod_add_cmd(&dline_msgtab);
520    mod_add_cmd(&undline_msgtab);
521 +  add_capability("DLN", CAP_DLN, 1);
522 +  add_capability("UNDLN", CAP_UNDLN, 1);
523   }
524  
525   static void
# Line 326 | Line 527 | module_exit(void)
527   {
528    mod_del_cmd(&dline_msgtab);
529    mod_del_cmd(&undline_msgtab);
530 +  delete_capability("UNDLN");
531 +  delete_capability("DLN");
532   }
533  
534   struct module module_entry = {

Diff Legend

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