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

Comparing:
ircd-hybrid-7.2/src/s_conf.c (file contents), Revision 201 by adx, Tue Nov 1 11:41:52 2005 UTC vs.
ircd-hybrid-8/src/s_conf.c (file contents), Revision 1157 by michael, Tue Aug 9 22:03:59 2011 UTC

# Line 23 | Line 23
23   */
24  
25   #include "stdinc.h"
26 + #include "list.h"
27   #include "ircd_defs.h"
28 < #include "tools.h"
28 > #include "balloc.h"
29   #include "s_conf.h"
30   #include "s_serv.h"
31   #include "resv.h"
31 #include "s_stats.h"
32   #include "channel.h"
33   #include "client.h"
34   #include "common.h"
# Line 38 | Line 38
38   #include "irc_string.h"
39   #include "sprintf_irc.h"
40   #include "s_bsd.h"
41 #include "irc_getnameinfo.h"
42 #include "irc_getaddrinfo.h"
41   #include "ircd.h"
44 #include "list.h"
42   #include "listener.h"
43   #include "hostmask.h"
44   #include "modules.h"
# Line 61 | Line 58 | struct Callback *client_check_cb = NULL;
58   struct config_server_hide ConfigServerHide;
59  
60   /* general conf items link list root, other than k lines etc. */
61 + dlink_list service_items = { NULL, NULL, 0 };
62   dlink_list server_items  = { NULL, NULL, 0 };
63   dlink_list cluster_items = { NULL, NULL, 0 };
64   dlink_list hub_items     = { NULL, NULL, 0 };
# Line 87 | Line 85 | extern char linebuf[];
85   extern char conffilebuf[IRCD_BUFSIZE];
86   extern char yytext[];
87   extern int yyparse(); /* defined in y.tab.c */
88 < unsigned int scount = 0; /* used by yyparse(), etc */
89 < int ypass  = 1; /* used by yyparse()      */
88 >
89 > struct conf_parser_context conf_parser_ctx = { 0, 0, NULL };
90  
91   /* internally defined functions */
92   static void lookup_confhost(struct ConfItem *);
# Line 117 | Line 115 | static void destroy_cidr_class(struct Cl
115  
116   static void flags_to_ascii(unsigned int, const unsigned int[], char *, int);
117  
120 FBFILE *conf_fbfile_in = NULL;
121
118   /* address of default class conf */
119   static struct ConfItem *class_default;
120  
# Line 141 | Line 137 | static BlockHeap *ip_entry_heap = NULL;
137   static int ip_entries_count = 0;
138  
139  
140 < inline void *
140 > void *
141   map_to_conf(struct ConfItem *aconf)
142   {
143    void *conf;
144 <  conf = (void *)((unsigned long)aconf +
145 <                  (unsigned long)sizeof(struct ConfItem));
144 >  conf = (void *)((uintptr_t)aconf +
145 >                  (uintptr_t)sizeof(struct ConfItem));
146    return(conf);
147   }
148  
149 < inline struct ConfItem *
149 > struct ConfItem *
150   unmap_conf_item(void *aconf)
151   {
152    struct ConfItem *conf;
153  
154 <  conf = (struct ConfItem *)((unsigned long)aconf -
155 <                             (unsigned long)sizeof(struct ConfItem));
154 >  conf = (struct ConfItem *)((uintptr_t)aconf -
155 >                             (uintptr_t)sizeof(struct ConfItem));
156    return(conf);
157   }
158  
# Line 171 | Line 167 | unmap_conf_item(void *aconf)
167   * if successful save hp in the conf item it was called with
168   */
169   static void
170 < conf_dns_callback(void *vptr, struct DNSReply *reply)
170 > conf_dns_callback(void *vptr, const struct irc_ssaddr *addr, const char *name)
171   {
172 <  struct AccessItem *aconf = (struct AccessItem *)vptr;
177 <  struct ConfItem *conf;
172 >  struct AccessItem *aconf = vptr;
173  
174 <  MyFree(aconf->dns_query);
180 <  aconf->dns_query = NULL;
174 >  aconf->dns_pending = 0;
175  
176 <  if (reply != NULL)
177 <    memcpy(&aconf->ipnum, &reply->addr, sizeof(reply->addr));
178 <  else {
179 <    ilog(L_NOTICE, "Host not found: %s, ignoring connect{} block",
186 <         aconf->host);
187 <    conf = unmap_conf_item(aconf);
188 <    sendto_realops_flags(UMODE_ALL, L_ALL,
189 <                         "Ignoring connect{} block for %s - host not found",
190 <                         conf->name);
191 <    delete_conf_item(conf);
192 <  }
176 >  if (addr != NULL)
177 >    memcpy(&aconf->ipnum, addr, sizeof(aconf->ipnum));
178 >  else
179 >    aconf->dns_failed = 1;
180   }
181  
182   /* conf_dns_lookup()
# Line 201 | Line 188 | conf_dns_callback(void *vptr, struct DNS
188   static void
189   conf_dns_lookup(struct AccessItem *aconf)
190   {
191 <  if (aconf->dns_query == NULL)
191 >  if (!aconf->dns_pending)
192    {
193 <    aconf->dns_query = MyMalloc(sizeof(struct DNSQuery));
194 <    aconf->dns_query->ptr = aconf;
208 <    aconf->dns_query->callback = conf_dns_callback;
209 <    gethost_byname(aconf->host, aconf->dns_query);
193 >    aconf->dns_pending = 1;
194 >    gethost_byname(conf_dns_callback, aconf, aconf->host);
195    }
196   }
197  
# Line 306 | Line 291 | make_conf_item(ConfType type)
291                                         sizeof(struct MatchItem));
292      dlinkAdd(conf, &conf->node, &xconf_items);
293      break;
294 <
294 > #ifdef HAVE_LIBPCRE
295    case RXLINE_TYPE:
296      conf = (struct ConfItem *)MyMalloc(sizeof(struct ConfItem) +
297                                         sizeof(struct MatchItem));
# Line 320 | Line 305 | make_conf_item(ConfType type)
305      aconf->status = CONF_KLINE;
306      dlinkAdd(conf, &conf->node, &rkconf_items);
307      break;
308 <
308 > #endif
309    case CLUSTER_TYPE:
310      conf = (struct ConfItem *)MyMalloc(sizeof(struct ConfItem));
311      dlinkAdd(conf, &conf->node, &cluster_items);
# Line 337 | Line 322 | make_conf_item(ConfType type)
322      dlinkAdd(conf, &conf->node, &nresv_items);
323      break;
324  
325 +  case SERVICE_TYPE:
326 +    status = CONF_SERVICE;
327 +    conf = MyMalloc(sizeof(struct ConfItem));
328 +    dlinkAdd(conf, &conf->node, &service_items);
329 +    break;
330 +
331    case CLASS_TYPE:
332 <    conf = (struct ConfItem *)MyMalloc(sizeof(struct ConfItem) +
333 <                                       sizeof(struct ClassItem));
332 >    conf = MyMalloc(sizeof(struct ConfItem) +
333 >                           sizeof(struct ClassItem));
334      dlinkAdd(conf, &conf->node, &class_items);
335 <    aclass = (struct ClassItem *)map_to_conf(conf);
336 <    ConFreq(aclass)  = DEFAULT_CONNECTFREQUENCY;
335 >
336 >    aclass = map_to_conf(conf);
337 >    aclass->active = 1;
338 >    ConFreq(aclass) = DEFAULT_CONNECTFREQUENCY;
339      PingFreq(aclass) = DEFAULT_PINGFREQUENCY;
340      MaxTotal(aclass) = MAXIMUM_LINKS_DEFAULT;
341      MaxSendq(aclass) = DEFAULT_SENDQ;
342 <    CurrUserCount(aclass) = 0;
342 >
343      break;
344  
345    default:
# Line 357 | Line 350 | make_conf_item(ConfType type)
350    /* XXX Yes, this will core if default is hit. I want it to for now - db */
351    conf->type = type;
352  
353 <  return(conf);
353 >  return conf;
354   }
355  
356   void
357   delete_conf_item(struct ConfItem *conf)
358   {
359 +  dlink_node *m = NULL;
360    struct MatchItem *match_item;
361    struct AccessItem *aconf;
362    ConfType type = conf->type;
# Line 381 | Line 375 | delete_conf_item(struct ConfItem *conf)
375    case SERVER_TYPE:
376      aconf = map_to_conf(conf);
377  
378 <    if (aconf->dns_query != NULL)
379 <    {
386 <      delete_resolver_queries(aconf->dns_query);
387 <      MyFree(aconf->dns_query);
388 <    }
378 >    if (aconf->dns_pending)
379 >      delete_resolver_queries(aconf);
380      if (aconf->passwd != NULL)
381        memset(aconf->passwd, 0, strlen(aconf->passwd));
382      if (aconf->spasswd != NULL)
# Line 398 | Line 389 | delete_conf_item(struct ConfItem *conf)
389      MyFree(aconf->oper_reason);
390      MyFree(aconf->user);
391      MyFree(aconf->host);
401    MyFree(aconf->fakename);
392   #ifdef HAVE_LIBCRYPTO
393      if (aconf->rsa_public_key)
394        RSA_free(aconf->rsa_public_key);
# Line 478 | Line 468 | delete_conf_item(struct ConfItem *conf)
468      dlinkDelete(&conf->node, &xconf_items);
469      MyFree(conf);
470      break;
471 <
471 > #ifdef HAVE_LIBPCRE
472    case RKLINE_TYPE:
473      aconf = map_to_conf(conf);
474      MyFree(aconf->regexuser);
# Line 501 | Line 491 | delete_conf_item(struct ConfItem *conf)
491      dlinkDelete(&conf->node, &rxconf_items);
492      MyFree(conf);
493      break;
494 <
494 > #endif
495    case NRESV_TYPE:
496      match_item = map_to_conf(conf);
497      MyFree(match_item->user);
# Line 509 | Line 499 | delete_conf_item(struct ConfItem *conf)
499      MyFree(match_item->reason);
500      MyFree(match_item->oper_reason);
501      dlinkDelete(&conf->node, &nresv_items);
502 +
503 +    if (conf->flags & CONF_FLAGS_TEMPORARY)
504 +      if ((m = dlinkFindDelete(&temporary_resv, conf)) != NULL)
505 +        free_dlink_node(m);
506 +
507      MyFree(conf);
508      break;
509  
# Line 526 | Line 521 | delete_conf_item(struct ConfItem *conf)
521      break;
522  
523    case CRESV_TYPE:
524 +    if (conf->flags & CONF_FLAGS_TEMPORARY)
525 +      if ((m = dlinkFindDelete(&temporary_resv, conf)) != NULL)
526 +        free_dlink_node(m);
527 +
528      MyFree(conf);
529      break;
530  
# Line 534 | Line 533 | delete_conf_item(struct ConfItem *conf)
533      MyFree(conf);
534      break;
535  
536 +  case SERVICE_TYPE:
537 +    dlinkDelete(&conf->node, &service_items);
538 +    MyFree(conf);
539 +    break;
540 +
541    default:
542      break;
543    }
# Line 576 | Line 580 | report_confitem_types(struct Client *sou
580    struct ClassItem *classitem = NULL;
581    char buf[12];
582    char *p = NULL;
583 +  const char *pfx = NULL;
584  
585    switch (type)
586    {
# Line 618 | Line 623 | report_confitem_types(struct Client *sou
623      }
624      break;
625  
626 + #ifdef HAVE_LIBPCRE
627    case RXLINE_TYPE:
628      DLINK_FOREACH(ptr, rxconf_items.head)
629      {
# Line 632 | Line 638 | report_confitem_types(struct Client *sou
638      break;
639  
640    case RKLINE_TYPE:
641 <    p = temp ? "Rk" : "RK";
641 >    pfx = temp ? "kR" : "KR";
642  
643      DLINK_FOREACH(ptr, rkconf_items.head)
644      {
# Line 642 | Line 648 | report_confitem_types(struct Client *sou
648          continue;
649  
650        sendto_one(source_p, form_str(RPL_STATSKLINE), me.name,
651 <                 source_p->name, p, aconf->host, aconf->user,
651 >                 source_p->name, pfx, aconf->host, aconf->user,
652                   aconf->reason, aconf->oper_reason ? aconf->oper_reason : "");
653      }
654      break;
655 + #endif
656  
657    case ULINE_TYPE:
658      DLINK_FOREACH(ptr, uconf_items.head)
# Line 712 | Line 719 | report_confitem_types(struct Client *sou
719                   me.name, source_p->name, 'Y',
720                   conf->name, PingFreq(classitem),
721                   ConFreq(classitem),
722 <                 MaxTotal(classitem), MaxSendq(classitem));
722 >                 MaxTotal(classitem), MaxSendq(classitem),
723 >                 CurrUserCount(classitem),
724 >                 classitem->active ? "active" : "disabled");
725      }
726      break;
727  
# Line 720 | Line 729 | report_confitem_types(struct Client *sou
729    case CLIENT_TYPE:
730      break;
731  
732 +  case SERVICE_TYPE: /* XXX TBD */
733 +    DLINK_FOREACH(ptr, service_items.head)
734 +    {
735 +      conf = ptr->data;
736 +    }
737 +    break;
738 +
739    case SERVER_TYPE:
740      DLINK_FOREACH(ptr, server_items.head)
741      {
# Line 734 | Line 750 | report_confitem_types(struct Client *sou
750          *p++ = 'A';
751        if (IsConfCryptLink(aconf))
752          *p++ = 'C';
737      if (IsConfLazyLink(aconf))
738        *p++ = 'L';
739      if (aconf->fakename)
740        *p++ = 'M';
753        if (IsConfTopicBurst(aconf))
754          *p++ = 'T';
755        if (IsConfCompressed(aconf))
# Line 747 | Line 759 | report_confitem_types(struct Client *sou
759  
760        *p = '\0';
761  
762 <      /* Allow admins to see actual ips
763 <       * unless hide_server_ips is enabled
762 >      /*
763 >       * Allow admins to see actual ips unless hide_server_ips is enabled
764         */
765        if (!ConfigServerHide.hide_server_ips && IsAdmin(source_p))
766          sendto_one(source_p, form_str(RPL_STATSCLINE),
# Line 790 | Line 802 | report_confitem_types(struct Client *sou
802    case CRESV_TYPE:
803    case NRESV_TYPE:
804    case CLUSTER_TYPE:
805 +  default:
806      break;
807    }
808   }
# Line 816 | Line 829 | check_client(va_list args)
829  
830    /* I'm already in big trouble if source_p->localClient is NULL -db */
831    if ((i = verify_access(source_p, username)))
819  {
832      ilog(L_INFO, "Access denied: %s[%s]",
833           source_p->name, source_p->sockhost);
822  }
834  
835    switch (i)
836    {
826    case IRCD_SOCKET_ERROR:
827      exit_client(source_p, &me, "Socket Error");
828      break;
829
837      case TOO_MANY:
838        sendto_realops_flags(UMODE_FULL, L_ALL,
839                             "Too many on IP for %s (%s).",
# Line 834 | Line 841 | check_client(va_list args)
841                             source_p->sockhost);
842        ilog(L_INFO,"Too many connections on IP from %s.",
843             get_client_name(source_p, SHOW_IP));
844 <      ServerStats->is_ref++;
844 >      ++ServerStats.is_ref;
845        exit_client(source_p, &me, "No more connections allowed on that IP");
846        break;
847  
# Line 845 | Line 852 | check_client(va_list args)
852                             source_p->sockhost);
853        ilog(L_INFO,"Too many connections from %s.",
854             get_client_name(source_p, SHOW_IP));
855 <       ServerStats->is_ref++;
855 >      ++ServerStats.is_ref;
856        exit_client(source_p, &me,
857                  "No more connections allowed in your connection class");
858        break;
859  
860      case NOT_AUTHORIZED:
861 <    {
855 <      static char ipaddr[HOSTIPLEN];
856 <      ServerStats->is_ref++;
861 >      ++ServerStats.is_ref;
862        /* jdc - lists server name & port connections are on */
863        /*       a purely cosmetical change */
859      irc_getnameinfo((struct sockaddr*)&source_p->localClient->ip,
860            source_p->localClient->ip.ss_len, ipaddr, HOSTIPLEN, NULL, 0,
861            NI_NUMERICHOST);
864        sendto_realops_flags(UMODE_UNAUTH, L_ALL,
865                             "Unauthorized client connection from %s [%s] on [%s/%u].",
866                             get_client_name(source_p, SHOW_IP),
867 <                           ipaddr,
867 >                           source_p->sockhost,
868                             source_p->localClient->listener->name,
869                             source_p->localClient->listener->port);
870        ilog(L_INFO,
# Line 875 | Line 877 | check_client(va_list args)
877         * capture reject code here or rely on the connecting too fast code.
878         * - Dianora
879         */
880 <      if(REJECT_HOLD_TIME > 0)
880 >      if (REJECT_HOLD_TIME > 0)
881        {
882          sendto_one(source_p, ":%s NOTICE %s :You are not authorized to use this server",
883                     me.name, source_p->name);
# Line 885 | Line 887 | check_client(va_list args)
887        else
888          exit_client(source_p, &me, "You are not authorized to use this server");
889        break;
890 <    }
889 <
890 >
891     case BANNED_CLIENT:
892       /*
893        * Don't exit them immediately, play with them a bit.
# Line 899 | Line 900 | check_client(va_list args)
900       }
901       else
902         exit_client(source_p, &me, "Banned");
903 <     ServerStats->is_ref++;
903 >     ++ServerStats.is_ref;
904       break;
905  
906     case 0:
# Line 1016 | Line 1017 | attach_iline(struct Client *client_p, st
1017    ip_found->count++;
1018    SetIpHash(client_p);
1019  
1020 <  aconf = (struct AccessItem *)map_to_conf(conf);
1020 >  aconf = map_to_conf(conf);
1021    if (aconf->class_ptr == NULL)
1022      return NOT_AUTHORIZED;  /* If class is missing, this is best */
1023  
1024 <  aclass = (struct ClassItem *)map_to_conf(aconf->class_ptr);
1024 >  aclass = map_to_conf(aconf->class_ptr);
1025  
1026    count_user_host(client_p->username, client_p->host,
1027                    &global, &local, &ident);
# Line 1031 | Line 1032 | attach_iline(struct Client *client_p, st
1032     */
1033    if (MaxTotal(aclass) != 0 && CurrUserCount(aclass) >= MaxTotal(aclass))
1034      a_limit_reached = 1;
1035 <  else if (MaxPerIp(aclass) != 0 && ip_found->count >= MaxPerIp(aclass))
1035 >  else if (MaxPerIp(aclass) != 0 && ip_found->count > MaxPerIp(aclass))
1036      a_limit_reached = 1;
1037    else if (MaxLocal(aclass) != 0 && local >= MaxLocal(aclass))
1038      a_limit_reached = 1;
# Line 1044 | Line 1045 | attach_iline(struct Client *client_p, st
1045    if (a_limit_reached)
1046    {
1047      if (!IsConfExemptLimits(aconf))
1048 <      return TOO_MANY;  /* Already at maximum allowed */
1048 >      return TOO_MANY;   /* Already at maximum allowed */
1049  
1050      sendto_one(client_p,
1051                 ":%s NOTICE %s :*** Your connection class is full, "
# Line 1193 | Line 1194 | hash_ip(struct irc_ssaddr *addr)
1194    {
1195      struct sockaddr_in *v4 = (struct sockaddr_in *)addr;
1196      int hash;
1197 <    u_int32_t ip;
1197 >    uint32_t ip;
1198  
1199      ip   = ntohl(v4->sin_addr.s_addr);
1200      hash = ((ip >> 12) + ip) & (IP_HASH_SIZE-1);
# Line 1204 | Line 1205 | hash_ip(struct irc_ssaddr *addr)
1205    {
1206      int hash;
1207      struct sockaddr_in6 *v6 = (struct sockaddr_in6 *)addr;
1208 <    u_int32_t *ip = (u_int32_t *)&v6->sin6_addr.s6_addr;
1208 >    uint32_t *ip = (uint32_t *)&v6->sin6_addr.s6_addr;
1209  
1210      hash  = ip[0] ^ ip[3];
1211      hash ^= hash >> 16;  
# Line 1228 | Line 1229 | hash_ip(struct irc_ssaddr *addr)
1229   * used in the hash.
1230   */
1231   void
1232 < count_ip_hash(int *number_ips_stored, unsigned long *mem_ips_stored)
1232 > count_ip_hash(unsigned int *number_ips_stored, uint64_t *mem_ips_stored)
1233   {
1234    struct ip_entry *ptr;
1235    int i;
# Line 1316 | Line 1317 | detach_conf(struct Client *client_p, Con
1317        case CLIENT_TYPE:
1318        case OPER_TYPE:
1319        case SERVER_TYPE:
1320 <        aconf = (struct AccessItem *)map_to_conf(conf);
1320 >        aconf = map_to_conf(conf);
1321 >
1322 >        assert(aconf->clients > 0);
1323 >
1324          if ((aclass_conf = ClassPtr(aconf)) != NULL)
1325          {
1326 <          aclass = (struct ClassItem *)map_to_conf(aclass_conf);
1326 >          aclass = map_to_conf(aclass_conf);
1327 >
1328 >          assert(aclass->curr_user_count > 0);
1329  
1330            if (conf->type == CLIENT_TYPE)
1331              remove_from_cidr_check(&client_p->localClient->ip, aclass);
1332 <
1327 <          if (CurrUserCount(aclass) > 0)
1328 <            aclass->curr_user_count--;
1329 <          if (MaxTotal(aclass) < 0 && CurrUserCount(aclass) <= 0)
1332 >          if (--aclass->curr_user_count == 0 && aclass->active == 0)
1333              delete_conf_item(aclass_conf);
1334          }
1335  
1336 <        /* Please, no ioccc entries - Dianora */
1334 <        if (aconf->clients > 0)
1335 <          --aconf->clients;
1336 <        if (aconf->clients == 0 && IsConfIllegal(aconf))
1336 >        if (--aconf->clients == 0 && IsConfIllegal(aconf))
1337            delete_conf_item(conf);
1338 +
1339          break;
1340 +
1341        case LEAF_TYPE:
1342        case HUB_TYPE:
1343 <        match_item = (struct MatchItem *)map_to_conf(conf);
1343 >        match_item = map_to_conf(conf);
1344          if (match_item->ref_count == 0 && match_item->illegal)
1345            delete_conf_item(conf);
1346          break;
# Line 1367 | Line 1369 | detach_conf(struct Client *client_p, Con
1369   int
1370   attach_conf(struct Client *client_p, struct ConfItem *conf)
1371   {
1370  struct AccessItem *aconf;
1371  struct MatchItem *match_item;
1372
1372    if (dlinkFind(&client_p->localClient->confs, conf) != NULL)
1373      return 1;
1374  
# Line 1377 | Line 1376 | attach_conf(struct Client *client_p, str
1376        conf->type == SERVER_TYPE ||
1377        conf->type == OPER_TYPE)
1378    {
1379 <    aconf = (struct AccessItem *)map_to_conf(conf);
1379 >    struct AccessItem *aconf = map_to_conf(conf);
1380 >    struct ClassItem *aclass = map_to_conf(aconf->class_ptr);
1381  
1382      if (IsConfIllegal(aconf))
1383        return NOT_AUTHORIZED;
1384  
1385      if (conf->type == CLIENT_TYPE)
1386    {
1387      struct ClassItem *aclass;
1388      aclass = (struct ClassItem *)map_to_conf(aconf->class_ptr);
1389
1386        if (cidr_limit_reached(IsConfExemptLimits(aconf),
1387                               &client_p->localClient->ip, aclass))
1388 <        return TOO_MANY;  /* Already at maximum allowed */
1393 <
1394 <      CurrUserCount(aclass)++;
1395 <    }
1388 >        return TOO_MANY;    /* Already at maximum allowed */
1389  
1390 +    CurrUserCount(aclass)++;
1391      aconf->clients++;
1392    }
1393    else if (conf->type == HUB_TYPE || conf->type == LEAF_TYPE)
1394    {
1395 <    match_item = (struct MatchItem *)map_to_conf(conf);
1395 >    struct MatchItem *match_item = map_to_conf(conf);
1396      match_item->ref_count++;
1397    }
1398  
# Line 1432 | Line 1426 | attach_connect_block(struct Client *clie
1426    DLINK_FOREACH(ptr, server_items.head)
1427    {
1428      conf = ptr->data;
1429 <    aconf = (struct AccessItem *)map_to_conf(conf);
1429 >    aconf = map_to_conf(conf);
1430  
1431      if (match(conf->name, name) == 0 || match(aconf->host, host) == 0)
1432        continue;
# Line 1472 | Line 1466 | find_conf_exact(ConfType type, const cha
1466  
1467      if (conf->name == NULL)
1468        continue;
1469 <    aconf = (struct AccessItem *)map_to_conf(conf);
1469 >    aconf = map_to_conf(conf);
1470      if (aconf->host == NULL)
1471        continue;
1472      if (irccmp(conf->name, name) != 0)
# Line 1483 | Line 1477 | find_conf_exact(ConfType type, const cha
1477      ** socket host) matches *either* host or name field
1478      ** of the configuration.
1479      */
1480 <    if (!match(aconf->host, host) || !match(aconf->user,user)
1487 <        || irccmp(conf->name, name) )
1480 >    if (!match(aconf->host, host) || !match(aconf->user, user))
1481        continue;
1482      if (type == OPER_TYPE)
1483      {
1484 <      struct ClassItem *aclass;
1484 >      struct ClassItem *aclass = map_to_conf(aconf->class_ptr);
1485  
1486 <      aclass = (struct ClassItem *)aconf->class_ptr;
1494 <      if (aconf->clients < MaxTotal(aclass))
1495 <        return conf;
1496 <      else
1486 >      if (aconf->clients >= MaxTotal(aclass))
1487          continue;
1488      }
1489 <    else
1490 <      return conf;
1489 >
1490 >    return conf;
1491    }
1492 +
1493    return NULL;
1494   }
1495  
# Line 1599 | Line 1590 | find_matching_name_conf(ConfType type, c
1590  
1591    switch (type)
1592    {
1593 <    case RXLINE_TYPE:
1593 > #ifdef HAVE_LIBPCRE
1594 >  case RXLINE_TYPE:
1595        DLINK_FOREACH(ptr, list_p->head)
1596        {
1597          conf = ptr->data;
# Line 1609 | Line 1601 | find_matching_name_conf(ConfType type, c
1601            return conf;
1602        }
1603        break;
1604 + #endif
1605 +  case SERVICE_TYPE:
1606 +    DLINK_FOREACH(ptr, list_p->head)
1607 +    {
1608 +      conf = ptr->data;
1609 +
1610 +      if (EmptyString(conf->name))
1611 +        continue;
1612 +      if ((name != NULL) && !irccmp(name, conf->name))
1613 +        return conf;
1614 +    }
1615 +    break;
1616  
1617    case XLINE_TYPE:
1618    case ULINE_TYPE:
# Line 1773 | Line 1777 | rehash(int sig)
1777      sendto_realops_flags(UMODE_ALL, L_ALL,
1778                           "Got signal SIGHUP, reloading ircd.conf file");
1779  
1776 #ifndef _WIN32
1780    restart_resolver();
1781 < #endif
1781 >
1782    /* don't close listeners until we know we can go ahead with the rehash */
1783  
1784    /* Check to see if we magically got(or lost) IPv6 support */
# Line 1786 | Line 1789 | rehash(int sig)
1789    if (ServerInfo.description != NULL)
1790      strlcpy(me.info, ServerInfo.description, sizeof(me.info));
1791  
1789 #ifndef STATIC_MODULES
1792    load_conf_modules();
1791 #endif
1793  
1794    flush_deleted_I_P();
1795  
# Line 1834 | Line 1835 | set_default_conf(void)
1835    ServerInfo.specific_ipv6_vhost = 0;
1836  
1837    ServerInfo.max_clients = MAXCLIENTS_MAX;
1838 <  /* Don't reset hub, as that will break lazylinks */
1839 <  /* ServerInfo.hub = NO; */
1838 >
1839 >  ServerInfo.hub = 0;
1840    ServerInfo.dns_host.sin_addr.s_addr = 0;
1841    ServerInfo.dns_host.sin_port = 0;
1842    AdminInfo.name = NULL;
# Line 1853 | Line 1854 | set_default_conf(void)
1854    ConfigLoggingEntry.ioerrlog[0] = '\0';
1855    ConfigLoggingEntry.failed_operlog[0] = '\0';
1856  
1857 +  ConfigChannel.disable_fake_channels = NO;
1858    ConfigChannel.restrict_channels = NO;
1859    ConfigChannel.disable_local_channels = NO;
1860    ConfigChannel.use_invex = YES;
# Line 1877 | Line 1879 | set_default_conf(void)
1879    DupString(ConfigServerHide.hidden_name, NETWORK_NAME_DEFAULT);
1880    ConfigServerHide.hide_server_ips = NO;
1881  
1882 +  
1883 +  DupString(ConfigFileEntry.service_name, SERVICE_NAME_DEFAULT);
1884 +  ConfigFileEntry.max_watch = WATCHSIZE_DEFAULT;
1885    ConfigFileEntry.gline_min_cidr = 16;
1886    ConfigFileEntry.gline_min_cidr6 = 48;
1887    ConfigFileEntry.invisible_on_connect = YES;
# Line 1888 | Line 1893 | set_default_conf(void)
1893    ConfigFileEntry.disable_auth = NO;
1894    ConfigFileEntry.disable_remote = NO;
1895    ConfigFileEntry.kill_chase_time_limit = 90;
1896 <  ConfigFileEntry.default_floodcount = 8; /* XXX */
1896 >  ConfigFileEntry.default_floodcount = 8;
1897    ConfigFileEntry.failed_oper_notice = YES;
1898 <  ConfigFileEntry.dots_in_ident = 0;      /* XXX */
1894 <  ConfigFileEntry.dot_in_ip6_addr = YES;
1898 >  ConfigFileEntry.dots_in_ident = 0;
1899    ConfigFileEntry.min_nonwildcard = 4;
1900    ConfigFileEntry.min_nonwildcard_simple = 3;
1901    ConfigFileEntry.max_accept = 20;
1902 <  ConfigFileEntry.anti_nick_flood = NO;   /* XXX */
1902 >  ConfigFileEntry.anti_nick_flood = NO;
1903    ConfigFileEntry.max_nick_time = 20;
1904    ConfigFileEntry.max_nick_changes = 5;
1905 <  ConfigFileEntry.anti_spam_exit_message_time = 0;  /* XXX */
1905 >  ConfigFileEntry.anti_spam_exit_message_time = 0;
1906    ConfigFileEntry.ts_warn_delta = TS_WARN_DELTA_DEFAULT;
1907 <  ConfigFileEntry.ts_max_delta = TS_MAX_DELTA_DEFAULT;  /* XXX */
1907 >  ConfigFileEntry.ts_max_delta = TS_MAX_DELTA_DEFAULT;
1908    ConfigFileEntry.kline_with_reason = YES;
1909    ConfigFileEntry.kline_reason = NULL;
1910    ConfigFileEntry.warn_no_nline = YES;
1911 <  ConfigFileEntry.stats_o_oper_only = NO; /* XXX */
1911 >  ConfigFileEntry.stats_o_oper_only = NO;
1912    ConfigFileEntry.stats_k_oper_only = 1;  /* masked */
1913    ConfigFileEntry.stats_i_oper_only = 1;  /* masked */
1914    ConfigFileEntry.stats_P_oper_only = NO;
# Line 1914 | Line 1918 | set_default_conf(void)
1918    ConfigFileEntry.pace_wait_simple = 1;
1919    ConfigFileEntry.short_motd = NO;
1920    ConfigFileEntry.ping_cookie = NO;
1921 <  ConfigFileEntry.no_oper_flood = NO;     /* XXX */
1922 <  ConfigFileEntry.true_no_oper_flood = NO;  /* XXX */
1921 >  ConfigFileEntry.no_oper_flood = NO;
1922 >  ConfigFileEntry.true_no_oper_flood = NO;
1923    ConfigFileEntry.oper_pass_resv = YES;
1924 <  ConfigFileEntry.glines = NO;            /* XXX */
1925 <  ConfigFileEntry.gline_time = 12 * 3600; /* XXX */
1924 >  ConfigFileEntry.glines = NO;
1925 >  ConfigFileEntry.gline_time = 12 * 3600;
1926    ConfigFileEntry.idletime = 0;
1927    ConfigFileEntry.max_targets = MAX_TARGETS_DEFAULT;
1928    ConfigFileEntry.client_flood = CLIENT_FLOOD_DEFAULT;
1929 <  ConfigFileEntry.oper_only_umodes = UMODE_DEBUG;  /* XXX */
1930 <  ConfigFileEntry.oper_umodes = UMODE_LOCOPS | UMODE_SERVNOTICE |
1931 <    UMODE_OPERWALL | UMODE_WALLOP;        /* XXX */
1929 >  ConfigFileEntry.oper_only_umodes = UMODE_DEBUG;
1930 >  ConfigFileEntry.oper_umodes = UMODE_BOTS | UMODE_LOCOPS | UMODE_SERVNOTICE |
1931 >    UMODE_OPERWALL | UMODE_WALLOP;
1932    DupString(ConfigFileEntry.servlink_path, SLPATH);
1933   #ifdef HAVE_LIBCRYPTO
1934    /* jdc -- This is our default value for a cipher.  According to the
# Line 1954 | Line 1958 | set_default_conf(void)
1958   static void
1959   read_conf(FBFILE *file)
1960   {
1961 <  scount = lineno = 0;
1961 >  lineno = 0;
1962  
1963    set_default_conf(); /* Set default values prior to conf parsing */
1964 <  ypass = 1;
1964 >  conf_parser_ctx.pass = 1;
1965    yyparse();          /* pick up the classes first */
1966  
1967    fbrewind(file);
1968  
1969 <  ypass = 2;
1969 >  conf_parser_ctx.pass = 2;
1970    yyparse();          /* Load the values from the conf */
1971    validate_conf();    /* Check to make sure some values are still okay. */
1972                        /* Some global values are also loaded here. */
# Line 1987 | Line 1991 | validate_conf(void)
1991    if (ServerInfo.network_desc == NULL)
1992      DupString(ServerInfo.network_desc,NETWORK_DESC_DEFAULT);
1993  
1994 +  if (ConfigFileEntry.service_name == NULL)
1995 +    DupString(ConfigFileEntry.service_name, SERVICE_NAME_DEFAULT);
1996 +
1997    if ((ConfigFileEntry.client_flood < CLIENT_FLOOD_MIN) ||
1998        (ConfigFileEntry.client_flood > CLIENT_FLOOD_MAX))
1999      ConfigFileEntry.client_flood = CLIENT_FLOOD_MAX;
2000 +
2001 +  ConfigFileEntry.max_watch = IRCD_MAX(ConfigFileEntry.max_watch, WATCHSIZE_MIN);
2002   }
2003  
2004   /* lookup_confhost()
# Line 2028 | Line 2037 | lookup_confhost(struct ConfItem *conf)
2037    /* Get us ready for a bind() and don't bother doing dns lookup */
2038    hints.ai_flags = AI_PASSIVE | AI_NUMERICHOST;
2039  
2040 <  if (irc_getaddrinfo(aconf->host, NULL, &hints, &res))
2040 >  if (getaddrinfo(aconf->host, NULL, &hints, &res))
2041    {
2042      conf_dns_lookup(aconf);
2043      return;
# Line 2039 | Line 2048 | lookup_confhost(struct ConfItem *conf)
2048    memcpy(&aconf->ipnum, res->ai_addr, res->ai_addrlen);
2049    aconf->ipnum.ss_len = res->ai_addrlen;
2050    aconf->ipnum.ss.ss_family = res->ai_family;
2051 <  irc_freeaddrinfo(res);
2051 >  freeaddrinfo(res);
2052   }
2053  
2054   /* conf_connect_allowed()
# Line 2078 | Line 2087 | conf_connect_allowed(struct irc_ssaddr *
2087   static struct AccessItem *
2088   find_regexp_kline(const char *uhi[])
2089   {
2090 + #ifdef HAVE_LIBPCRE
2091    const dlink_node *ptr = NULL;
2092  
2093    DLINK_FOREACH(ptr, rkconf_items.head)
# Line 2092 | Line 2102 | find_regexp_kline(const char *uhi[])
2102           !ircd_pcre_exec(aptr->regexhost, uhi[2])))
2103        return aptr;
2104    }
2105 <
2105 > #endif
2106    return NULL;
2107   }
2108  
# Line 2266 | Line 2276 | expire_tklines(dlink_list *tklist)
2276            }
2277          }
2278  
2279 +        dlinkDelete(ptr, tklist);
2280          delete_one_address_conf(aconf->host, aconf);
2270        dlinkDelete(ptr, tklist);
2281        }
2282      }
2283      else if (conf->type == XLINE_TYPE ||
# Line 2321 | Line 2331 | expire_tklines(dlink_list *tklist)
2331          if (ConfigFileEntry.tkline_expire_notices)
2332            sendto_realops_flags(UMODE_ALL, L_ALL,
2333                                 "Temporary RESV for [%s] expired", cconf->name);
2334 <        dlinkDelete(ptr, tklist);
2325 <        free_dlink_node(ptr);
2326 <        delete_conf_item(conf);
2334 >        delete_channel_resv(cconf);
2335        }
2336      }
2337    }
# Line 2392 | Line 2400 | get_oper_name(const struct Client *clien
2400    struct AccessItem *aconf;
2401  
2402    /* +5 for !,@,{,} and null */
2403 <  static char buffer[NICKLEN+USERLEN+HOSTLEN+HOSTLEN+5];
2403 >  static char buffer[NICKLEN + USERLEN + HOSTLEN + HOSTLEN + 5];
2404  
2405    if (MyConnect(client_p))
2406    {
# Line 2403 | Line 2411 | get_oper_name(const struct Client *clien
2411  
2412        if (IsConfOperator(aconf))
2413        {
2414 <        ircsprintf(buffer, "%s!%s@%s{%s}", client_p->name,
2415 <                   client_p->username, client_p->host,
2408 <                   conf->name);
2414 >        snprintf(buffer, sizeof(buffer), "%s!%s@%s{%s}", client_p->name,
2415 >                 client_p->username, client_p->host, conf->name);
2416          return buffer;
2417        }
2418      }
# Line 2416 | Line 2423 | get_oper_name(const struct Client *clien
2423      assert(0); /* Oper without oper conf! */
2424    }
2425  
2426 <  ircsprintf(buffer, "%s!%s@%s{%s}", client_p->name,
2427 <             client_p->username, client_p->host, client_p->servptr->name);
2426 >  snprintf(buffer, sizeof(buffer), "%s!%s@%s{%s}", client_p->name,
2427 >           client_p->username, client_p->host, client_p->servptr->name);
2428    return buffer;
2429   }
2430  
# Line 2434 | Line 2441 | read_conf_files(int cold)
2441    char chanmodes[32];
2442    char chanlimit[32];
2443  
2444 +  conf_parser_ctx.boot = cold;
2445    filename = get_conf_name(CONF_TYPE);
2446  
2447    /* We need to know the initial filename for the yyerror() to report
# Line 2444 | Line 2452 | read_conf_files(int cold)
2452    */
2453    strlcpy(conffilebuf, filename, sizeof(conffilebuf));
2454  
2455 <  if ((conf_fbfile_in = fbopen(filename, "r")) == NULL)
2455 >  if ((conf_parser_ctx.conf_file = fbopen(filename, "r")) == NULL)
2456    {
2457      if (cold)
2458      {
# Line 2464 | Line 2472 | read_conf_files(int cold)
2472    if (!cold)
2473      clear_out_old_conf();
2474  
2475 <  read_conf(conf_fbfile_in);
2476 <  fbclose(conf_fbfile_in);
2475 >  read_conf(conf_parser_ctx.conf_file);
2476 >  fbclose(conf_parser_ctx.conf_file);
2477  
2478    add_isupport("NETWORK", ServerInfo.network_name, -1);
2479 <  ircsprintf(chanmodes, "b%s%s:%d", ConfigChannel.use_except ? "e" : "",
2480 <             ConfigChannel.use_invex ? "I" : "", ConfigChannel.max_bans);
2479 >  snprintf(chanmodes, sizeof(chanmodes), "b%s%s:%d",
2480 >           ConfigChannel.use_except ? "e" : "",
2481 >           ConfigChannel.use_invex ? "I" : "", ConfigChannel.max_bans);
2482    add_isupport("MAXLIST", chanmodes, -1);
2483    add_isupport("MAXTARGETS", NULL, ConfigFileEntry.max_targets);
2484 +
2485    if (ConfigChannel.disable_local_channels)
2486      add_isupport("CHANTYPES", "#", -1);
2487    else
2488      add_isupport("CHANTYPES", "#&", -1);
2489 <  ircsprintf(chanlimit, "%s:%d", ConfigChannel.disable_local_channels ? "#" : "#&",
2490 <             ConfigChannel.max_chans_per_user);
2489 >
2490 >  snprintf(chanlimit, sizeof(chanlimit), "%s:%d",
2491 >           ConfigChannel.disable_local_channels ? "#" : "#&",
2492 >           ConfigChannel.max_chans_per_user);
2493    add_isupport("CHANLIMIT", chanlimit, -1);
2494 <  ircsprintf(chanmodes, "%s%s%s", ConfigChannel.use_except ? "e" : "",
2495 <             ConfigChannel.use_invex ? "I" : "", "b,k,l,imnpst");
2494 >  snprintf(chanmodes, sizeof(chanmodes), "%s%s%s",
2495 >           ConfigChannel.use_except ? "e" : "",
2496 >           ConfigChannel.use_invex ? "I" : "", "b,k,l,imnpstOS");
2497    add_isupport("CHANNELLEN", NULL, LOCAL_CHANNELLEN);
2498 +
2499    if (ConfigChannel.use_except)
2500      add_isupport("EXCEPTS", "e", -1);
2501    if (ConfigChannel.use_invex)
# Line 2494 | Line 2508 | read_conf_files(int cold)
2508     */
2509    rebuild_isupport_message_line();
2510  
2511 <  parse_conf_file(KLINE_TYPE, cold);
2511 > #ifdef HAVE_LIBPCRE
2512    parse_conf_file(RKLINE_TYPE, cold);
2513 +  parse_conf_file(RXLINE_TYPE, cold);
2514 + #endif
2515 +  parse_conf_file(KLINE_TYPE, cold);
2516    parse_conf_file(DLINE_TYPE, cold);
2517    parse_conf_file(XLINE_TYPE, cold);
2501  parse_conf_file(RXLINE_TYPE, cold);
2518    parse_conf_file(NRESV_TYPE, cold);
2519    parse_conf_file(CRESV_TYPE, cold);
2520   }
# Line 2549 | Line 2565 | clear_out_old_conf(void)
2565    dlink_list *free_items [] = {
2566      &server_items,   &oconf_items,    &hub_items, &leaf_items,
2567       &uconf_items,   &xconf_items, &rxconf_items, &rkconf_items,
2568 <     &nresv_items, &cluster_items,  &gdeny_items, NULL
2568 >     &nresv_items, &cluster_items,  &gdeny_items, &service_items, NULL
2569    };
2570  
2571    dlink_list ** iterator = free_items; /* C is dumb */
# Line 2566 | Line 2582 | clear_out_old_conf(void)
2582        /* XXX This is less than pretty */
2583        if (conf->type == SERVER_TYPE)
2584        {
2585 <        aconf = (struct AccessItem *)map_to_conf(conf);
2585 >        aconf = map_to_conf(conf);
2586 >
2587          if (aconf->clients != 0)
2588          {
2589            SetConfIllegal(aconf);
# Line 2579 | Line 2596 | clear_out_old_conf(void)
2596        }
2597        else if (conf->type == OPER_TYPE)
2598        {
2599 <        aconf = (struct AccessItem *)map_to_conf(conf);
2599 >        aconf = map_to_conf(conf);
2600 >
2601          if (aconf->clients != 0)
2602          {
2603            SetConfIllegal(aconf);
# Line 2592 | Line 2610 | clear_out_old_conf(void)
2610        }
2611        else if (conf->type == CLIENT_TYPE)
2612        {
2613 <        aconf = (struct AccessItem *)map_to_conf(conf);
2613 >        aconf = map_to_conf(conf);
2614 >
2615          if (aconf->clients != 0)
2616          {
2617            SetConfIllegal(aconf);
# Line 2617 | Line 2636 | clear_out_old_conf(void)
2636        {
2637          if ((conf->type == LEAF_TYPE) || (conf->type == HUB_TYPE))
2638          {
2639 <          match_item = (struct MatchItem *)map_to_conf(conf);
2640 <          if ((match_item->ref_count <= 0))
2639 >          match_item = map_to_conf(conf);
2640 >          if (match_item->ref_count <= 0)
2641              delete_conf_item(conf);
2642            else
2643            {
# Line 2632 | Line 2651 | clear_out_old_conf(void)
2651      }
2652    }
2653  
2654 <  /* don't delete the class table, rather mark all entries
2654 >  /*
2655 >   * don't delete the class table, rather mark all entries
2656     * for deletion. The table is cleaned up by check_class. - avalon
2657     */
2658    DLINK_FOREACH(ptr, class_items.head)
2659    {
2660 <    conf = ptr->data;
2661 <    cltmp = (struct ClassItem *)map_to_conf(conf);
2660 >    cltmp = map_to_conf(ptr->data);
2661 >
2662      if (ptr != class_items.tail)  /* never mark the "default" class */
2663 <      MaxTotal(cltmp) = -1;
2663 >      cltmp->active = 0;
2664    }
2665  
2666    clear_out_address_conf();
2667  
2668    /* clean out module paths */
2649 #ifndef STATIC_MODULES
2669    mod_clear_paths();
2651 #endif
2670  
2671    /* clean out ServerInfo */
2672    MyFree(ServerInfo.description);
# Line 2690 | Line 2708 | clear_out_old_conf(void)
2708     */
2709  
2710    /* clean out general */
2711 +  MyFree(ConfigFileEntry.service_name);
2712 +  ConfigFileEntry.service_name = NULL;
2713 +
2714    MyFree(ConfigFileEntry.servlink_path);
2715    ConfigFileEntry.servlink_path = NULL;
2716   #ifdef HAVE_LIBCRYPTO
# Line 2890 | Line 2911 | find_class(const char *classname)
2911    struct ConfItem *conf;
2912  
2913    if ((conf = find_exact_name_conf(CLASS_TYPE, classname, NULL, NULL)) != NULL)
2914 <    return(conf);
2914 >    return conf;
2915  
2916    return class_default;
2917   }
# Line 2904 | Line 2925 | find_class(const char *classname)
2925   void
2926   check_class(void)
2927   {
2928 <  dlink_node *ptr;
2908 <  dlink_node *next_ptr;
2909 <  struct ConfItem *conf;
2910 <  struct ClassItem *aclass;
2928 >  dlink_node *ptr = NULL, *next_ptr = NULL;
2929  
2930    DLINK_FOREACH_SAFE(ptr, next_ptr, class_items.head)
2931    {
2932 <    conf = ptr->data;
2915 <    aclass = (struct ClassItem *)map_to_conf(conf);
2932 >    struct ClassItem *aclass = map_to_conf(ptr->data);
2933  
2934 <    if (MaxTotal(aclass) < 0)
2934 >    if (!aclass->active && !CurrUserCount(aclass))
2935      {
2936        destroy_cidr_class(aclass);
2937 <      if (CurrUserCount(aclass) > 0)
2921 <        dlinkDelete(&conf->node, &class_items);
2922 <      else
2923 <        delete_conf_item(conf);
2937 >      delete_conf_item(ptr->data);
2938      }
2939    }
2940   }
# Line 2937 | Line 2951 | init_class(void)
2951    struct ClassItem *aclass;
2952  
2953    class_default = make_conf_item(CLASS_TYPE);
2954 <  aclass = (struct ClassItem *)map_to_conf(class_default);
2954 >
2955 >  aclass = map_to_conf(class_default);
2956 >  aclass->active = 1;
2957    DupString(class_default->name, "default");
2958    ConFreq(aclass)  = DEFAULT_CONNECTFREQUENCY;
2959    PingFreq(aclass) = DEFAULT_PINGFREQUENCY;
# Line 2953 | Line 2969 | init_class(void)
2969   * output       - sendq for this client as found from its class
2970   * side effects - NONE
2971   */
2972 < unsigned long
2972 > unsigned int
2973   get_sendq(struct Client *client_p)
2974   {
2975 <  unsigned long sendq = DEFAULT_SENDQ;
2975 >  unsigned int sendq = DEFAULT_SENDQ;
2976    dlink_node *ptr;
2977    struct ConfItem *conf;
2978    struct ConfItem *class_conf;
# Line 2996 | Line 3012 | get_sendq(struct Client *client_p)
3012   void
3013   conf_add_class_to_conf(struct ConfItem *conf, const char *class_name)
3014   {
3015 <  struct AccessItem *aconf;
3016 <  struct ClassItem *aclass;
3001 <
3002 <  aconf = (struct AccessItem *)map_to_conf(conf);
3015 >  struct AccessItem *aconf = map_to_conf(conf);
3016 >  struct ClassItem *class = NULL;
3017  
3018    if (class_name == NULL)
3019    {
3020      aconf->class_ptr = class_default;
3021 +
3022      if (conf->type == CLIENT_TYPE)
3023        sendto_realops_flags(UMODE_ALL, L_ALL,
3024                             "Warning *** Defaulting to default class for %s@%s",
# Line 3014 | Line 3029 | conf_add_class_to_conf(struct ConfItem *
3029                             conf->name);
3030    }
3031    else
3017  {
3032      aconf->class_ptr = find_class(class_name);
3019  }
3033  
3034 <  if (aconf->class_ptr == NULL)
3034 >  if (aconf->class_ptr)
3035 >    class = map_to_conf(aconf->class_ptr);
3036 >
3037 >  if (aconf->class_ptr == NULL || !class->active)
3038    {
3039      if (conf->type == CLIENT_TYPE)
3040        sendto_realops_flags(UMODE_ALL, L_ALL,
# Line 3030 | Line 3046 | conf_add_class_to_conf(struct ConfItem *
3046                             conf->name);
3047      aconf->class_ptr = class_default;
3048    }
3033  else
3034  {
3035    aclass = (struct ClassItem *)map_to_conf(aconf->class_ptr);
3036    if (MaxTotal(aclass) < 0)
3037    {
3038      aconf->class_ptr = class_default;
3039    }
3040  }
3049   }
3050  
3043 #define MAXCONFLINKS 150
3044
3051   /* conf_add_server()
3052   *
3053   * inputs       - pointer to config item
# Line 3050 | Line 3056 | conf_add_class_to_conf(struct ConfItem *
3056   * side effects - Add a connect block
3057   */
3058   int
3059 < conf_add_server(struct ConfItem *conf, unsigned int lcount, const char *class_name)
3059 > conf_add_server(struct ConfItem *conf, const char *class_name)
3060   {
3061    struct AccessItem *aconf;
3062 <  char *orig_host;
3062 >  struct split_nuh_item nuh;
3063 >  char conf_user[USERLEN + 1];
3064 >  char conf_host[HOSTLEN + 1];
3065  
3066    aconf = map_to_conf(conf);
3067  
3068    conf_add_class_to_conf(conf, class_name);
3069  
3070 <  if (lcount > MAXCONFLINKS || !aconf->host || !conf->name)
3070 >  if (!aconf->host || !conf->name)
3071    {
3072      sendto_realops_flags(UMODE_ALL, L_ALL, "Bad connect block");
3073      ilog(L_WARN, "Bad connect block");
# Line 3074 | Line 3082 | conf_add_server(struct ConfItem *conf, u
3082      return -1;
3083    }
3084  
3085 <  orig_host = aconf->host;
3086 <  split_nuh(orig_host, NULL, &aconf->user, &aconf->host);
3087 <  MyFree(orig_host);
3085 >  nuh.nuhmask  = aconf->host;
3086 >  nuh.nickptr  = NULL;
3087 >  nuh.userptr  = conf_user;
3088 >  nuh.hostptr  = conf_host;
3089 >
3090 >  nuh.nicksize = 0;
3091 >  nuh.usersize = sizeof(conf_user);
3092 >  nuh.hostsize = sizeof(conf_host);
3093 >
3094 >  split_nuh(&nuh);
3095 >
3096 >  MyFree(aconf->host);
3097 >  aconf->host = NULL;
3098 >
3099 >  DupString(aconf->user, conf_user); /* somehow username checking for servers
3100 >                                 got lost in H6/7, will have to be re-added */
3101 >  DupString(aconf->host, conf_host);
3102 >
3103    lookup_confhost(conf);
3104  
3105    return 0;
3106   }
3107  
3085 /* conf_add_d_conf()
3086 *
3087 * inputs       - pointer to config item
3088 * output       - NONE
3089 * side effects - Add a d/D line
3090 */
3091 void
3092 conf_add_d_conf(struct AccessItem *aconf)
3093 {
3094  if (aconf->host == NULL)
3095    return;
3096
3097  aconf->user = NULL;
3098
3099  /* XXX - Should 'd' ever be in the old conf? For new conf we don't
3100   *       need this anyway, so I will disable it for now... -A1kmm
3101   */
3102  if (parse_netmask(aconf->host, NULL, NULL) == HM_HOST)
3103  {
3104    ilog(L_WARN, "Invalid Dline %s ignored", aconf->host);
3105    free_access_item(aconf);
3106  }
3107  else
3108  {
3109    /* XXX ensure user is NULL */
3110    MyFree(aconf->user);
3111    aconf->user = NULL;
3112    add_conf_by_address(CONF_DLINE, aconf);
3113  }
3114 }
3115
3108   /* yyerror()
3109   *
3110   * inputs       - message from parser
# Line 3124 | Line 3116 | yyerror(const char *msg)
3116   {
3117    char newlinebuf[IRCD_BUFSIZE];
3118  
3119 <  if (ypass != 1)
3119 >  if (conf_parser_ctx.pass != 1)
3120      return;
3121  
3122    strip_tabs(newlinebuf, linebuf, sizeof(newlinebuf));
# Line 3160 | Line 3152 | conf_yy_fatal_error(const char *msg)
3152   * Originally written by Dianora (Diane, db@db.net)
3153   */
3154   time_t
3155 < valid_tkline(char *p, int minutes)
3155 > valid_tkline(const char *p, int minutes)
3156   {
3157    time_t result = 0;
3158  
3159 <  while (*p)
3159 >  for (; *p; ++p)
3160    {
3161 <    if (IsDigit(*p))
3170 <    {
3171 <      result *= 10;
3172 <      result += ((*p) & 0xF);
3173 <      p++;
3174 <    }
3175 <    else
3161 >    if (!IsDigit(*p))
3162        return 0;
3163 +
3164 +    result *= 10;
3165 +    result += ((*p) & 0xF);
3166    }
3167  
3168 <  /* in the degenerate case where oper does a /quote kline 0 user@host :reason
3168 >  /*
3169 >   * In the degenerate case where oper does a /quote kline 0 user@host :reason
3170     * i.e. they specifically use 0, I am going to return 1 instead
3171     * as a return value of non-zero is used to flag it as a temporary kline
3172     */
3183
3173    if (result == 0)
3174      result = 1;
3175  
# Line 3281 | Line 3270 | valid_wild_card(struct Client *source_p,
3270   *                if target_server is NULL and an "ON" is found error
3271   *                is reported.
3272   *                if reason pointer is NULL ignore pointer,
3273 < *                this allows usee of parse_a_line in unkline etc.
3273 > *                this allows use of parse_a_line in unkline etc.
3274   *
3275   * - Dianora
3276   */
# Line 3397 | Line 3386 | parse_aline(const char *cmd, struct Clie
3386  
3387    if (reason != NULL)
3388    {
3389 <    if (parc != 0)
3389 >    if (parc != 0 && !EmptyString(*parv))
3390      {
3391        *reason = *parv;
3392        if (!valid_comment(source_p, *reason, YES))
# Line 3436 | Line 3425 | find_user_host(struct Client *source_p,
3425    {
3426      /* Explicit user@host mask given */
3427  
3428 <    if(hostp != NULL)                            /* I'm a little user@host */
3428 >    if (hostp != NULL)                            /* I'm a little user@host */
3429      {
3430        *(hostp++) = '\0';                       /* short and squat */
3431        if (*user_host_or_nick)
# Line 3567 | Line 3556 | match_conf_password(const char *password
3556   */
3557   void
3558   cluster_a_line(struct Client *source_p, const char *command,
3559 <               int capab, int cluster_type, const char *pattern, ...)
3559 >               int capab, int cluster_type, const char *pattern, ...)
3560   {
3561    va_list args;
3562    char buffer[IRCD_BUFSIZE];
3563 <  struct ConfItem *conf;
3575 <  dlink_node *ptr;
3563 >  const dlink_node *ptr = NULL;
3564  
3565    va_start(args, pattern);
3566    vsnprintf(buffer, sizeof(buffer), pattern, args);
# Line 3580 | Line 3568 | cluster_a_line(struct Client *source_p,
3568  
3569    DLINK_FOREACH(ptr, cluster_items.head)
3570    {
3571 <    conf = ptr->data;
3571 >    const struct ConfItem *conf = ptr->data;
3572  
3573      if (conf->flags & cluster_type)
3586    {
3574        sendto_match_servs(source_p, conf->name, CAP_CLUSTER|capab,
3575                           "%s %s %s", command, conf->name, buffer);
3589    }
3576    }
3577   }
3578  
# Line 3618 | Line 3604 | cluster_a_line(struct Client *source_p,
3604   * @                            *       *       *
3605   * !                            *       *       *
3606   */
3621
3607   void
3608 < split_nuh(char *mask, char **nick, char **user, char **host)
3608 > split_nuh(struct split_nuh_item *const iptr)
3609   {
3610    char *p = NULL, *q = NULL;
3611  
3612 <  if ((p = strchr(mask, '!')) != NULL)
3612 >  if (iptr->nickptr)
3613 >    strlcpy(iptr->nickptr, "*", iptr->nicksize);
3614 >  if (iptr->userptr)
3615 >    strlcpy(iptr->userptr, "*", iptr->usersize);
3616 >  if (iptr->hostptr)
3617 >    strlcpy(iptr->hostptr, "*", iptr->hostsize);
3618 >
3619 >  if ((p = strchr(iptr->nuhmask, '!')))
3620    {
3621      *p = '\0';
3630    if (nick != NULL)
3631    {
3632      if (*mask != '\0')
3633        *nick = xstrldup(mask, NICKLEN);
3634      else
3635        DupString(*nick, "*");
3636    }
3622  
3623 <    if ((q = strchr(++p, '@')) != NULL)
3624 <    {
3625 <      *q = '\0';
3623 >    if (iptr->nickptr && *iptr->nuhmask != '\0')
3624 >      strlcpy(iptr->nickptr, iptr->nuhmask, iptr->nicksize);
3625 >
3626 >    if ((q = strchr(++p, '@'))) {
3627 >      *q++ = '\0';
3628  
3629        if (*p != '\0')
3630 <        *user = xstrldup(p, USERLEN+1);
3644 <      else
3645 <        DupString(*user, "*");
3630 >        strlcpy(iptr->userptr, p, iptr->usersize);
3631  
3632 <      if (*++q != '\0')
3633 <        *host = xstrldup(q, HOSTLEN+1);
3649 <      else
3650 <        DupString(*host, "*");
3632 >      if (*q != '\0')
3633 >        strlcpy(iptr->hostptr, q, iptr->hostsize);
3634      }
3635      else
3636      {
3637        if (*p != '\0')
3638 <        *user = xstrldup(p, USERLEN+1);
3656 <      else
3657 <        DupString(*user, "*");
3658 <
3659 <      DupString(*host, "*");
3638 >        strlcpy(iptr->userptr, p, iptr->usersize);
3639      }
3640    }
3641 <  else  /* No ! found so lets look for a user@host */
3641 >  else
3642    {
3643 <    if ((p = strchr(mask, '@')) != NULL)        /* if found a @ */
3643 >    /* No ! found so lets look for a user@host */
3644 >    if ((p = strchr(iptr->nuhmask, '@')))
3645      {
3646 <      if (nick != NULL)
3647 <        DupString(*nick, "*");
3668 <      *p = '\0';
3646 >      /* if found a @ */
3647 >      *p++ = '\0';
3648  
3649 <      if (*mask != '\0')
3650 <        *user = xstrldup(mask, USERLEN+1);
3672 <      else
3673 <        DupString(*user, "*");
3649 >      if (*iptr->nuhmask != '\0')
3650 >        strlcpy(iptr->userptr, iptr->nuhmask, iptr->usersize);
3651  
3652 <      if (*++p != '\0')
3653 <        *host = xstrldup(p, HOSTLEN+1);
3677 <      else
3678 <        DupString(*host, "*");
3652 >      if (*p != '\0')
3653 >        strlcpy(iptr->hostptr, p, iptr->hostsize);
3654      }
3655 <    else                                        /* no @ found */
3655 >    else
3656      {
3657 <      if (nick != NULL)
3658 <      {
3659 <        if (strpbrk(mask, ".:"))
3685 <        {
3686 <          DupString(*nick, "*");
3687 <          *host = xstrldup(mask, HOSTLEN+1);
3688 <        }
3689 <        else
3690 <        {
3691 <          *nick = xstrldup(mask, NICKLEN);
3692 <          DupString(*host, "*");
3693 <        }
3694 <
3695 <        DupString(*user, "*");
3696 <      }
3657 >      /* no @ found */
3658 >      if (!iptr->nickptr || strpbrk(iptr->nuhmask, ".:"))
3659 >        strlcpy(iptr->hostptr, iptr->nuhmask, iptr->hostsize);
3660        else
3661 <      {
3699 <        DupString(*user, "*");
3700 <        *host = xstrldup(mask, HOSTLEN+1);
3701 <      }
3661 >        strlcpy(iptr->nickptr, iptr->nuhmask, iptr->nicksize);
3662      }
3663    }
3664   }
# Line 3725 | Line 3685 | flags_to_ascii(unsigned int flags, const
3685    {
3686      if (flags & mask)
3687        *p++ = bit_table[i];
3688 <    else if(lowerit)
3688 >    else if (lowerit)
3689        *p++ = ToLower(bit_table[i]);
3690    }
3691    *p = '\0';
# Line 3932 | Line 3892 | rebuild_cidr_class(struct ConfItem *conf
3892   static void
3893   destroy_cidr_list(dlink_list *list)
3894   {
3895 <  dlink_node *ptr = NULL;
3936 <  dlink_node *next_ptr = NULL;
3937 <  struct CidrItem *cidr;
3895 >  dlink_node *ptr = NULL, *next_ptr = NULL;
3896  
3897    DLINK_FOREACH_SAFE(ptr, next_ptr, list->head)
3898    {
3941    cidr = ptr->data;
3899      dlinkDelete(ptr, list);
3900 <    MyFree(cidr);
3900 >    MyFree(ptr->data);
3901    }
3902   }
3903  

Diff Legend

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