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

Comparing:
ircd-hybrid-7.2/src/client.c (file contents), Revision 384 by michael, Tue Jan 31 12:22:01 2006 UTC vs.
ircd-hybrid-8/src/client.c (file contents), Revision 1176 by michael, Sun Aug 14 11:24:24 2011 UTC

# Line 23 | Line 23
23   */
24  
25   #include "stdinc.h"
26 < #include "tools.h"
26 > #include "list.h"
27   #include "client.h"
28   #include "channel_mode.h"
29   #include "common.h"
# Line 31 | Line 31
31   #include "fdlist.h"
32   #include "hash.h"
33   #include "irc_string.h"
34 #include "sprintf_irc.h"
34   #include "ircd.h"
36 #include "list.h"
35   #include "s_gline.h"
36   #include "numeric.h"
37   #include "packet.h"
# Line 53 | Line 51
51   #include "listener.h"
52   #include "irc_res.h"
53   #include "userhost.h"
54 + #include "watch.h"
55  
56   dlink_list listing_client_list = { NULL, NULL, 0 };
57   /* Pointer to beginning of Client list */
# Line 76 | Line 75 | static dlink_node *eac_next;  /* next ab
75  
76   static void check_pings_list(dlink_list *);
77   static void check_unknowns_list(void);
78 < static void ban_them(struct Client *client_p, struct ConfItem *conf);
78 > static void ban_them(struct Client *, struct ConfItem *);
79  
80  
81   /* init_client()
# Line 122 | Line 121 | make_client(struct Client *from)
121      client_p->since = client_p->lasttime = client_p->firsttime = CurrentTime;
122  
123      client_p->localClient = BlockHeapAlloc(lclient_heap);
124 +    client_p->localClient->registration = REG_INIT;
125      /* as good a place as any... */
126 <    dlinkAdd(client_p, make_dlink_node(), &unknown_list);
126 >    dlinkAdd(client_p, &client_p->localClient->lclient_node, &unknown_list);
127    }
128    else
129      client_p->from = from; /* 'from' of local client is self! */
# Line 252 | Line 252 | check_pings_list(dlink_list *list)
252        continue;
253      }
254  
255    if (GlobalSetOptions.idletime && IsClient(client_p))
256    {
257      if (!IsExemptKline(client_p) && !IsOper(client_p) &&
258          !IsIdlelined(client_p) &&
259          ((CurrentTime - client_p->localClient->last) > GlobalSetOptions.idletime))
260      {
261        struct ConfItem *conf;
262        struct AccessItem *aconf;
263
264        conf = make_conf_item(KLINE_TYPE);
265        aconf = (struct AccessItem *)map_to_conf(conf);
266
267        DupString(aconf->host, client_p->host);
268        DupString(aconf->reason, "idle exceeder");
269        DupString(aconf->user, client_p->username);
270        aconf->hold = CurrentTime + 60;
271        add_temp_line(conf);
272
273        sendto_realops_flags(UMODE_ALL, L_ALL,
274                             "Idle time limit exceeded for %s - temp k-lining",
275                             get_client_name(client_p, HIDE_IP));
276        exit_client(client_p, &me, aconf->reason);
277        continue;
278      }
279    }
280
255      if (!IsRegistered(client_p))
256        ping = CONNECTTIMEOUT, pingwarn = 0;
257      else
# Line 316 | Line 290 | check_pings_list(dlink_list *list)
290              ilog(L_NOTICE, "No response from %s, closing link",
291                   get_client_name(client_p, HIDE_IP));
292            }
319          ircsprintf(scratch, "Ping timeout: %d seconds",
320                     (int)(CurrentTime - client_p->lasttime));
293  
294 +          snprintf(scratch, sizeof(scratch), "Ping timeout: %d seconds",
295 +                   (int)(CurrentTime - client_p->lasttime));
296            exit_client(client_p, &me, scratch);
297          }
298          else if (!IsPingWarning(client_p) && pingwarn > 0 &&
# Line 362 | Line 336 | check_unknowns_list(void)
336      if (client_p->localClient->reject_delay > 0)
337      {
338        if (client_p->localClient->reject_delay <= CurrentTime)
339 <        exit_client(client_p, &me, "Rejected");
339 >        exit_client(client_p, &me, "Rejected");
340        continue;
341      }
342  
343 <    /* Check UNKNOWN connections - if they have been in this state
343 >    /*
344 >     * Check UNKNOWN connections - if they have been in this state
345       * for > 30s, close them.
346       */
347 <    if (client_p->firsttime ? ((CurrentTime - client_p->firsttime) > 30) : 0)
348 <      exit_client(client_p, &me, "Connection timed out");
347 >    if (IsAuthFinished(client_p) && (CurrentTime - client_p->firsttime) > 30)
348 >      exit_client(client_p, &me, "Registration timed out");
349    }
350   }
351  
# Line 552 | Line 527 | ban_them(struct Client *client_p, struct
527   static void
528   update_client_exit_stats(struct Client *client_p)
529   {
530 <  if (IsServer(client_p))
556 <  {
557 <    sendto_realops_flags(UMODE_EXTERNAL, L_ALL,
558 <                         "Server %s split from %s",
559 <                         client_p->name, client_p->servptr->name);
560 <  }
561 <  else if (IsClient(client_p))
530 >  if (IsClient(client_p))
531    {
532 +    assert(Count.total > 0);
533      --Count.total;
534      if (IsOper(client_p))
535        --Count.oper;
536      if (IsInvisible(client_p))
537        --Count.invisi;
538    }
539 +  else if (IsServer(client_p))
540 +    sendto_realops_flags(UMODE_EXTERNAL, L_ALL, "Server %s split from %s",
541 +                         client_p->name, client_p->servptr->name);
542  
543    if (splitchecking && !splitmode)
544      check_splitmode(NULL);
# Line 593 | Line 566 | find_person(const struct Client *client_
566      }
567    }
568    else
569 <    c2ptr = find_client(name);
569 >    c2ptr = hash_find_client(name);
570  
571    return ((c2ptr != NULL && IsClient(c2ptr)) ? c2ptr : NULL);
572   }
# Line 613 | Line 586 | find_chasing(struct Client *client_p, st
586      *chasing = 0;
587  
588    if (who)
589 <    return(who);
589 >    return who;
590  
591    if (IsDigit(*user))
592 <    return(NULL);
592 >    return NULL;
593  
594    if ((who = get_history(user,
595                          (time_t)ConfigFileEntry.kill_chase_time_limit))
# Line 624 | Line 597 | find_chasing(struct Client *client_p, st
597    {
598      sendto_one(source_p, form_str(ERR_NOSUCHNICK),
599                 me.name, source_p->name, user);
600 <    return(NULL);
600 >    return NULL;
601    }
602  
603    if (chasing)
604      *chasing = 1;
605  
606 <  return(who);
606 >  return who;
607   }
608  
609   /*
# Line 652 | Line 625 | find_chasing(struct Client *client_p, st
625   *        to modify what it points!!!
626   */
627   const char *
628 < get_client_name(struct Client *client, int showip)
628 > get_client_name(const struct Client *client, int showip)
629   {
630    static char nbuf[HOSTLEN * 2 + USERLEN + 5];
631  
632    assert(client != NULL);
633  
634    if (irccmp(client->name, client->host) == 0)
635 <    return(client->name);
635 >    return client->name;
636  
637    if (ConfigServerHide.hide_server_ips)
638      if (IsServer(client) || IsConnecting(client) || IsHandshake(client))
# Line 675 | Line 648 | get_client_name(struct Client *client, i
648      case SHOW_IP:
649        if (MyConnect(client))
650        {
651 <        ircsprintf(nbuf, "%s[%s@%s]", client->name, client->username,
652 <                   client->sockhost);
651 >        snprintf(nbuf, sizeof(nbuf), "%s[%s@%s]",
652 >                 client->name,
653 >                 client->username, client->sockhost);
654          break;
655        }
656      case MASK_IP:
657 <      ircsprintf(nbuf, "%s[%s@255.255.255.255]", client->name,
658 <                 client->username);
657 >      snprintf(nbuf, sizeof(nbuf), "%s[%s@255.255.255.255]",
658 >               client->name, client->username);
659        break;
660      default:
661 <      ircsprintf(nbuf, "%s[%s@%s]", client->name, client->username,
662 <                 client->host);
661 >      snprintf(nbuf, sizeof(nbuf), "%s[%s@%s]",
662 >               client->name,
663 >               client->username, client->host);
664    }
665  
666 <  return(nbuf);
666 >  return nbuf;
667   }
668  
669   void
670   free_exited_clients(void)
671   {
672 <  dlink_node *ptr, *next;
698 <  struct Client *target_p;
672 >  dlink_node *ptr = NULL, *next = NULL;
673    
674    DLINK_FOREACH_SAFE(ptr, next, dead_list.head)
675    {
676 <    target_p = ptr->data;
703 <
704 <    if (ptr->data == NULL)
705 <    {
706 <      sendto_realops_flags(UMODE_ALL, L_ALL,
707 <                           "Warning: null client on dead_list!");
708 <      dlinkDelete(ptr, &dead_list);
709 <      free_dlink_node(ptr);
710 <      continue;
711 <    }
712 <
713 <    free_client(target_p);
676 >    free_client(ptr->data);
677      dlinkDelete(ptr, &dead_list);
678      free_dlink_node(ptr);
679    }
# Line 729 | Line 692 | exit_one_client(struct Client *source_p,
692  
693    assert(!IsMe(source_p));
694  
695 <  if (IsServer(source_p))
733 <  {
734 <    dlinkDelete(&source_p->lnode, &source_p->servptr->serv->servers);
735 <
736 <    if ((lp = dlinkFindDelete(&global_serv_list, source_p)) != NULL)
737 <      free_dlink_node(lp);
738 <
739 <    if (!MyConnect(source_p))
740 <    {
741 <      source_p->from->serv->dep_servers--;
742 <      assert(source_p->from->serv->dep_servers > 0);
743 <    }
744 <  }
745 <  else if (IsClient(source_p))
695 >  if (IsClient(source_p))
696    {
697      if (source_p->servptr->serv != NULL)
698 <      dlinkDelete(&source_p->lnode, &source_p->servptr->serv->users);
698 >      dlinkDelete(&source_p->lnode, &source_p->servptr->serv->client_list);
699  
700 <    /* If a person is on a channel, send a QUIT notice
701 <    ** to every client (person) on the same channel (so
702 <    ** that the client can show the "**signoff" message).
703 <    ** (Note: The notice is to the local clients *only*)
704 <    */
700 >    /*
701 >     * If a person is on a channel, send a QUIT notice
702 >     * to every client (person) on the same channel (so
703 >     * that the client can show the "**signoff" message).
704 >     * (Note: The notice is to the local clients *only*)
705 >     */
706      sendto_common_channels_local(source_p, 0, ":%s!%s@%s QUIT :%s",
707                                   source_p->name, source_p->username,
708                                   source_p->host, quitmsg);
709      DLINK_FOREACH_SAFE(lp, next_lp, source_p->channel.head)
710        remove_user_from_channel(lp->data);
711  
761    /* Clean up allow lists */
762    del_all_accepts(source_p);
712      add_history(source_p, 0);
713      off_history(source_p);
714  
715 <    if (!MyConnect(source_p))
716 <    {
717 <      source_p->from->serv->dep_users--;
769 <      assert(source_p->from->serv->dep_users >= 0);
770 <    }
771 <    else
715 >    watch_check_hash(source_p, RPL_LOGOFF);
716 >
717 >    if (MyConnect(source_p))
718      {
719        /* Clean up invitefield */
720        DLINK_FOREACH_SAFE(lp, next_lp, source_p->localClient->invited.head)
721          del_invite(lp->data, source_p);
722 +
723 +      del_all_accepts(source_p);
724      }
725    }
726 +  else if (IsServer(source_p))
727 +  {
728 +    dlinkDelete(&source_p->lnode, &source_p->servptr->serv->server_list);
729 +
730 +    if ((lp = dlinkFindDelete(&global_serv_list, source_p)) != NULL)
731 +      free_dlink_node(lp);
732 +  }
733  
734    /* Remove source_p from the client lists */
735    if (HasID(source_p))
# Line 814 | Line 769 | exit_one_client(struct Client *source_p,
769   static void
770   recurse_send_quits(struct Client *original_source_p, struct Client *source_p,
771                     struct Client *from, struct Client *to, const char *comment,
772 <                   const char *splitstr, const char *myname)
772 >                   const char *splitstr)
773   {
774    dlink_node *ptr, *next;
775    struct Client *target_p;
776 <  int hidden = match(myname, source_p->name);
776 >  int hidden = match(me.name, source_p->name); /* XXX */
777  
778    assert(to != source_p);  /* should be already removed from serv_list */
779  
# Line 829 | Line 784 | recurse_send_quits(struct Client *origin
784     * hidden behind fakename. If so, send out the QUITs -adx
785     */
786    if (hidden || !IsCapable(to, CAP_QS))
787 <    DLINK_FOREACH_SAFE(ptr, next, source_p->serv->users.head)
787 >    DLINK_FOREACH_SAFE(ptr, next, source_p->serv->client_list.head)
788      {
789        target_p = ptr->data;
790        sendto_one(to, ":%s QUIT :%s", target_p->name, splitstr);
791      }
792  
793 <  DLINK_FOREACH_SAFE(ptr, next, source_p->serv->servers.head)
793 >  DLINK_FOREACH_SAFE(ptr, next, source_p->serv->server_list.head)
794      recurse_send_quits(original_source_p, ptr->data, from, to,
795 <                       comment, splitstr, myname);
795 >                       comment, splitstr);
796  
797    if (!hidden && ((source_p == original_source_p && to != from) ||
798                    !IsCapable(to, CAP_QS)))
# Line 859 | Line 814 | recurse_remove_clients(struct Client *so
814   {
815    dlink_node *ptr, *next;
816  
817 <  DLINK_FOREACH_SAFE(ptr, next, source_p->serv->users.head)
817 >  DLINK_FOREACH_SAFE(ptr, next, source_p->serv->client_list.head)
818      exit_one_client(ptr->data, quitmsg);
819  
820 <  DLINK_FOREACH_SAFE(ptr, next, source_p->serv->servers.head)
820 >  DLINK_FOREACH_SAFE(ptr, next, source_p->serv->server_list.head)
821    {
822      recurse_remove_clients(ptr->data, quitmsg);
823      exit_one_client(ptr->data, quitmsg);
824    }
870
871  assert(source_p->serv->dep_servers == 1);
872  assert(source_p->serv->dep_users == 0);
825   }
826  
827   /*
# Line 881 | Line 833 | static void
833   remove_dependents(struct Client *source_p, struct Client *from,
834                    const char *comment, const char *splitstr)
835   {
836 <  struct Client *to;
885 <  struct ConfItem *conf;
886 <  static char myname[HOSTLEN+1];
887 <  dlink_node *ptr;
836 >  dlink_node *ptr = NULL;
837  
838    DLINK_FOREACH(ptr, serv_list.head)
839 <  {
840 <    to = ptr->data;
892 <
893 <    if ((conf = to->serv->sconf) != NULL)
894 <      strlcpy(myname, my_name_for_link(conf), sizeof(myname));
895 <    else
896 <      strlcpy(myname, me.name, sizeof(myname));
897 <    recurse_send_quits(source_p, source_p, from, to,
898 <                       comment, splitstr, myname);
899 <  }
839 >    recurse_send_quits(source_p, source_p, from, ptr->data,
840 >                       comment, splitstr);
841  
842    recurse_remove_clients(source_p, splitstr);
843   }
# Line 922 | Line 863 | remove_dependents(struct Client *source_
863   void
864   exit_client(struct Client *source_p, struct Client *from, const char *comment)
865   {
866 <  dlink_node *m;
866 >  dlink_node *m = NULL;
867  
868    if (MyConnect(source_p))
869    {
# Line 937 | Line 878 | exit_client(struct Client *source_p, str
878      if (IsIpHash(source_p))
879        remove_one_ip(&source_p->localClient->ip);
880  
881 <    delete_auth(source_p);
881 >    if (source_p->localClient->auth)
882 >    {
883 >      delete_auth(source_p->localClient->auth);
884 >      source_p->localClient->auth = NULL;
885 >    }
886  
887      /* This source_p could have status of one of STAT_UNKNOWN, STAT_CONNECTING
888       * STAT_HANDSHAKE or STAT_UNKNOWN
# Line 947 | Line 892 | exit_client(struct Client *source_p, str
892       */
893      if (!IsRegistered(source_p))
894      {
895 <      if ((m = dlinkFindDelete(&unknown_list, source_p)) != NULL)
896 <        free_dlink_node(m);
895 >      assert(dlinkFind(&unknown_list, source_p));
896 >
897 >      dlinkDelete(&source_p->localClient->lclient_node, &unknown_list);
898      }
899      else if (IsClient(source_p))
900      {
901 +      assert(Count.local > 0);
902        Count.local--;
903  
904        if (IsOper(source_p))
# Line 960 | Line 907 | exit_client(struct Client *source_p, str
907            free_dlink_node(m);
908        }
909  
910 +      assert(dlinkFind(&local_client_list, source_p));
911        dlinkDelete(&source_p->localClient->lclient_node, &local_client_list);
912 +
913        if (source_p->localClient->list_task != NULL)
914          free_list_task(source_p->localClient->list_task, source_p);
915  
916 +      watch_del_watch_list(source_p);
917        sendto_realops_flags(UMODE_CCONN, L_ALL, "Client exiting: %s (%s@%s) [%s] [%s]",
918                             source_p->name, source_p->username, source_p->host, comment,
919                             ConfigFileEntry.hide_spoof_ips && IsIPSpoof(source_p) ?
920                             "255.255.255.255" : source_p->sockhost);
921 +      sendto_realops_flags(UMODE_CCONN_FULL, L_ALL, "CLIEXIT: %s %s %s %s 0 %s",
922 +                           source_p->name,
923 +                           source_p->username,
924 +                           source_p->host,
925 +
926 +                           ConfigFileEntry.hide_spoof_ips && IsIPSpoof(source_p) ?
927 +                           "255.255.255.255" : source_p->sockhost,
928 +                           comment);
929      }
930  
931      /* As soon as a client is known to be a server of some sort
# Line 984 | Line 942 | exit_client(struct Client *source_p, str
942        }
943  
944        if (IsServer(source_p))
987      {
945          Count.myserver--;
989        if (ServerInfo.hub)
990          remove_lazylink_flags(source_p->localClient->serverMask);
991        else
992          uplink = NULL;
993      }
946      }
947  
948      log_user_exit(source_p);
# Line 1030 | Line 982 | exit_client(struct Client *source_p, str
982      assert(source_p->serv != NULL && source_p->servptr != NULL);
983  
984      if (ConfigServerHide.hide_servers)
985 <      /* set netsplit message to "*.net *.split" to still show
985 >      /*
986 >       * Set netsplit message to "*.net *.split" to still show
987         * that its a split, but hide the servers splitting
988         */
989        strcpy(splitstr, "*.net *.split");
# Line 1055 | Line 1008 | exit_client(struct Client *source_p, str
1008    }
1009    else if (IsClient(source_p) && !IsKilled(source_p))
1010    {
1011 <    sendto_server(NULL, source_p, NULL, CAP_TS6, NOCAPS, NOFLAGS,
1011 >    sendto_server(from->from, NULL, CAP_TS6, NOCAPS,
1012                    ":%s QUIT :%s", ID(source_p), comment);
1013 <    sendto_server(NULL, source_p, NULL, NOCAPS, CAP_TS6, NOFLAGS,
1013 >    sendto_server(from->from, NULL, NOCAPS, CAP_TS6,
1014                    ":%s QUIT :%s", source_p->name, comment);
1015    }
1016  
# Line 1135 | Line 1088 | dead_link_on_read(struct Client *client_
1088      }
1089      else
1090      {
1091 <      report_error(L_ADMIN, "Lost connection to %s: %d",
1091 >      report_error(L_ADMIN, "Lost connection to %s: %s",
1092                     get_client_name(client_p, SHOW_IP), current_error);
1093 <      report_error(L_OPER, "Lost connection to %s: %d",
1093 >      report_error(L_OPER, "Lost connection to %s: %s",
1094                     get_client_name(client_p, MASK_IP), current_error);
1095      }
1096  
# Line 1153 | Line 1106 | dead_link_on_read(struct Client *client_
1106      strlcpy(errmsg, "Remote host closed the connection",
1107              sizeof(errmsg));
1108    else
1109 <    ircsprintf(errmsg, "Read error: %s",
1110 <               strerror(current_error));
1109 >    snprintf(errmsg, sizeof(errmsg), "Read error: %s",
1110 >             strerror(current_error));
1111  
1112    exit_client(client_p, &me, errmsg);
1113   }
# Line 1194 | Line 1147 | exit_aborted_clients(void)
1147  
1148   /*
1149   * accept processing, this adds a form of "caller ID" to ircd
1150 < *
1150 > *
1151   * If a client puts themselves into "caller ID only" mode,
1152 < * only clients that match a client pointer they have put on
1152 > * only clients that match a client pointer they have put on
1153   * the accept list will be allowed to message them.
1154   *
1155 < * [ source.on_allow_list ] -> [ target1 ] -> [ target2 ]
1203 < *
1204 < * [target.allow_list] -> [ source1 ] -> [source2 ]
1205 < *
1206 < * i.e. a target will have a link list of source pointers it will allow
1207 < * each source client then has a back pointer pointing back
1208 < * to the client that has it on its accept list.
1209 < * This allows for exit_one_client to remove these now bogus entries
1210 < * from any client having an accept on them.
1155 > * Diane Bruce, "Dianora" db@db.net
1156   */
1157  
1158 < /* accept_message()
1159 < *
1215 < * inputs       - pointer to source client
1216 < *              - pointer to target client
1217 < * output       - 1 if accept this message 0 if not
1218 < * side effects - See if source is on target's allow list
1219 < */
1220 < int
1221 < accept_message(struct Client *source, struct Client *target)
1158 > void
1159 > del_accept(struct split_nuh_item *accept_p, struct Client *client_p)
1160   {
1161 <  dlink_node *ptr;
1224 <
1225 <  DLINK_FOREACH(ptr, target->allow_list.head)
1226 <  {
1227 <    struct Client *target_p = ptr->data;
1228 <
1229 <    if (source == target_p)
1230 <      return (1);
1231 <  }
1161 >  dlinkDelete(&accept_p->node, &client_p->localClient->acceptlist);
1162  
1163 <  if (IsSoftCallerId(target))
1164 <  {
1165 <    DLINK_FOREACH(ptr, target->channel.head)
1166 <      if (IsMember(source, ((struct Membership *)ptr->data)->chptr))
1237 <        return (1);
1238 <  }
1239 <
1240 <  return (0);
1163 >  MyFree(accept_p->nickptr);
1164 >  MyFree(accept_p->userptr);
1165 >  MyFree(accept_p->hostptr);
1166 >  MyFree(accept_p);
1167   }
1168  
1169 < /* del_from_accept()
1170 < *
1171 < * inputs       - pointer to source client
1246 < *              - pointer to target client
1247 < * output       - NONE
1248 < * side effects - Delete's source pointer to targets allow list
1249 < *
1250 < * Walk through the target's accept list, remove if source is found,
1251 < * Then walk through the source's on_accept_list remove target if found.
1252 < */
1253 < void
1254 < del_from_accept(struct Client *source, struct Client *target)
1169 > struct split_nuh_item *
1170 > find_accept(const char *nick, const char *user,
1171 >            const char *host, struct Client *client_p, int do_match)
1172   {
1173 <  dlink_node *ptr;
1174 <  dlink_node *ptr2;
1175 <  dlink_node *next_ptr;
1259 <  dlink_node *next_ptr2;
1260 <  struct Client *target_p;
1173 >  dlink_node *ptr = NULL;
1174 >  /* XXX We wouldn't need that if match() would return 0 on match */
1175 >  int (*cmpfunc)(const char *, const char *) = do_match ? match : irccmp;
1176  
1177 <  DLINK_FOREACH_SAFE(ptr, next_ptr, target->allow_list.head)
1177 >  DLINK_FOREACH(ptr, client_p->localClient->acceptlist.head)
1178    {
1179 <    target_p = ptr->data;
1179 >    struct split_nuh_item *accept_p = ptr->data;
1180  
1181 <    if (source == target_p)
1182 <    {
1183 <      dlinkDelete(ptr, &target->allow_list);
1184 <      free_dlink_node(ptr);
1270 <
1271 <      DLINK_FOREACH_SAFE(ptr2, next_ptr2, source->on_allow_list.head)
1272 <      {
1273 <        target_p = ptr2->data;
1274 <
1275 <        if (target == target_p)
1276 <        {
1277 <          dlinkDelete(ptr2, &source->on_allow_list);
1278 <          free_dlink_node(ptr2);
1279 <        }
1280 <      }
1281 <    }
1181 >    if (cmpfunc(accept_p->nickptr, nick) == do_match &&
1182 >        cmpfunc(accept_p->userptr, user) == do_match &&
1183 >        cmpfunc(accept_p->hostptr, host) == do_match)
1184 >      return accept_p;
1185    }
1186 +
1187 +  return NULL;
1188   }
1189  
1190 < /* del_all_accepts()
1190 > /* accept_message()
1191   *
1192 < * inputs       - pointer to exiting client
1193 < * output       - NONE
1194 < * side effects - Walk through given clients allow_list and on_allow_list
1195 < *                remove all references to this client
1192 > * inputs       - pointer to source client
1193 > *              - pointer to target client
1194 > * output       - 1 if accept this message 0 if not
1195 > * side effects - See if source is on target's allow list
1196   */
1197 < void
1198 < del_all_accepts(struct Client *client_p)
1197 > int
1198 > accept_message(struct Client *source,
1199 >               struct Client *target)
1200   {
1201 <  dlink_node *ptr, *next_ptr;
1201 >  dlink_node *ptr = NULL;
1202  
1203 <  DLINK_FOREACH_SAFE(ptr, next_ptr, client_p->allow_list.head)
1204 <    del_from_accept(ptr->data, client_p);
1203 >  if (source == target || find_accept(source->name, source->username,
1204 >                                      source->host, target, 1))
1205 >    return 1;
1206  
1207 <  DLINK_FOREACH_SAFE(ptr, next_ptr, client_p->on_allow_list.head)
1208 <    del_from_accept(client_p, ptr->data);
1209 < }
1210 <
1304 < /* del_all_their_accepts()
1305 < *
1306 < * inputs       - pointer to exiting client
1307 < * output       - NONE
1308 < * side effects - Walk through given clients on_allow_list
1309 < *                remove all references to this client,
1310 < *                allow this client to keep their own allow_list
1311 < */
1312 < void
1313 < del_all_their_accepts(struct Client *client_p)
1314 < {
1315 <  dlink_node *ptr, *next_ptr;
1207 >  if (IsSoftCallerId(target))
1208 >    DLINK_FOREACH(ptr, target->channel.head)
1209 >      if (IsMember(source, ((struct Membership *)ptr->data)->chptr))
1210 >        return 1;
1211  
1212 <  DLINK_FOREACH_SAFE(ptr, next_ptr, client_p->on_allow_list.head)
1318 <    del_from_accept(client_p, ptr->data);
1212 >  return 0;
1213   }
1214  
1215 < /* set_initial_nick()
1322 < *
1323 < * inputs
1324 < * output
1325 < * side effects -
1215 > /* del_all_accepts()
1216   *
1217 < * This function is only called to set up an initially registering
1218 < * client.
1217 > * inputs       - pointer to exiting client
1218 > * output       - NONE
1219 > * side effects - Walk through given clients acceptlist and remove all entries
1220   */
1221   void
1222 < set_initial_nick(struct Client *client_p, struct Client *source_p,
1332 <                 const char *nick)
1222 > del_all_accepts(struct Client *client_p)
1223   {
1224 < char buf[USERLEN + 1];
1335 <
1336 <  /* Client setting NICK the first time */
1337 <  
1338 <  /* This had to be copied here to avoid problems.. */
1339 <  source_p->tsinfo = CurrentTime;
1224 >  dlink_node *ptr = NULL, *next_ptr = NULL;
1225  
1226 <  if (source_p->name[0])
1227 <    hash_del_client(source_p);
1343 <
1344 <  strlcpy(source_p->name, nick, sizeof(source_p->name));
1345 <  hash_add_client(source_p);
1346 <
1347 <  /* fd_desc is long enough */
1348 <  fd_note(&client_p->localClient->fd, "Nick: %s", nick);
1349 <  
1350 <  /* They have the nick they want now.. */
1351 <  client_p->llname[0] = '\0';
1352 <
1353 <  if (source_p->flags & FLAGS_GOTUSER)
1354 <  {
1355 <    strlcpy(buf, source_p->username, sizeof(buf));
1356 <
1357 <    /*
1358 <     * USER already received, now we have NICK.
1359 <     * *NOTE* For servers "NICK" *must* precede the
1360 <     * user message (giving USER before NICK is possible
1361 <     * only for local client connection!). register_user
1362 <     * may reject the client and call exit_client for it
1363 <     * --must test this and exit m_nick too!!!
1364 <     */
1365 <    register_local_user(client_p, source_p, nick, buf);
1366 <  }
1226 >  DLINK_FOREACH_SAFE(ptr, next_ptr, client_p->localClient->acceptlist.head)
1227 >    del_accept(ptr->data, client_p);
1228   }
1229  
1230   /* change_local_nick()
# Line 1377 | Line 1238 | set_initial_nick(struct Client *client_p
1238   void
1239   change_local_nick(struct Client *client_p, struct Client *source_p, const char *nick)
1240   {
1241 +  int samenick = 0;
1242 +
1243 +  assert(source_p->name[0] && !EmptyString(nick));
1244 +
1245    /*
1246 <  ** Client just changing his/her nick. If he/she is
1247 <  ** on a channel, send note of change to all clients
1248 <  ** on that channel. Propagate notice to other servers.
1249 <  */
1246 >   * Client just changing his/her nick. If he/she is
1247 >   * on a channel, send note of change to all clients
1248 >   * on that channel. Propagate notice to other servers.
1249 >   */
1250    if ((source_p->localClient->last_nick_change +
1251         ConfigFileEntry.max_nick_time) < CurrentTime)
1252      source_p->localClient->number_of_nick_changes = 0;
# Line 1394 | Line 1259 | change_local_nick(struct Client *client_
1259       !ConfigFileEntry.anti_nick_flood ||
1260       (IsOper(source_p) && ConfigFileEntry.no_oper_flood))
1261    {
1262 <    if (irccmp(source_p->name, nick))
1262 >    samenick = !irccmp(source_p->name, nick);
1263 >
1264 >    if (!samenick)
1265 >    {
1266        source_p->tsinfo = CurrentTime;
1267 +      clear_ban_cache_client(source_p);
1268 +      watch_check_hash(source_p, RPL_LOGOFF);
1269 +
1270 +      if (HasUMode(source_p, UMODE_REGISTERED))
1271 +      {
1272 +        unsigned int oldmodes = source_p->umodes;
1273 +        char modebuf[IRCD_BUFSIZE] = { '\0' };
1274 +
1275 +        DelUMode(source_p, UMODE_REGISTERED);
1276 +        send_umode(source_p, source_p, oldmodes, 0xffffffff, modebuf);
1277 +      }
1278 +    }
1279  
1280      /* XXX - the format of this notice should eventually be changed
1281       * to either %s[%s@%s], or even better would be get_client_name() -bill
# Line 1405 | Line 1285 | change_local_nick(struct Client *client_
1285      sendto_common_channels_local(source_p, 1, ":%s!%s@%s NICK :%s",
1286                                   source_p->name, source_p->username,
1287                                   source_p->host, nick);
1408
1288      add_history(source_p, 1);
1289 <          
1290 <         /* Only hubs care about lazy link nicks not being sent on yet
1412 <           * lazylink leafs/leafs always send their nicks up to hub,
1413 <           * hence must always propagate nick changes.
1414 <           * hubs might not propagate a nick change, if the leaf
1415 <           * does not know about that client yet.
1416 <           */
1417 <    sendto_server(client_p, source_p, NULL, CAP_TS6, NOCAPS, NOFLAGS,
1289 >
1290 >    sendto_server(client_p, NULL, CAP_TS6, NOCAPS,
1291                    ":%s NICK %s :%lu",
1292                    ID(source_p), nick, (unsigned long)source_p->tsinfo);
1293 <    sendto_server(client_p, source_p, NULL, NOCAPS, CAP_TS6, NOFLAGS,
1293 >    sendto_server(client_p, NULL, NOCAPS, CAP_TS6,
1294                    ":%s NICK %s :%lu",
1295                    source_p->name, nick, (unsigned long)source_p->tsinfo);
1296 +
1297 +    hash_del_client(source_p);
1298 +    strcpy(source_p->name, nick);
1299 +    hash_add_client(source_p);
1300 +
1301 +    if (!samenick)
1302 +      watch_check_hash(source_p, RPL_LOGON);
1303 +
1304 +    /* fd_desc is long enough */
1305 +    fd_note(&client_p->localClient->fd, "Nick: %s", nick);
1306    }
1307    else
1425  {
1308      sendto_one(source_p, form_str(ERR_NICKTOOFAST),
1309                 me.name, source_p->name, source_p->name,
1310                 nick, ConfigFileEntry.max_nick_time);
1429    return;
1430  }
1431
1432  /* Finally, add to hash */
1433  if (source_p->name[0])
1434    hash_del_client(source_p);
1435
1436  strcpy(source_p->name, nick);
1437  hash_add_client(source_p);
1438
1439  /* Make sure everyone that has this client on its accept list
1440   * loses that reference.
1441   */
1442  del_all_their_accepts(source_p);
1443
1444  /* fd_desc is long enough */
1445  fd_note(&client_p->localClient->fd, "Nick: %s", nick);
1311   }

Diff Legend

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