Author: Bleep <helveytw@home.com>
[ircu2.10.12-pk.git] / ircd / client.c
1 /*
2  * IRC - Internet Relay Chat, ircd/client.c
3  * Copyright (C) 1990 Darren Reed
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 1, or (at your option)
8  * any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18  *
19  * $Id$
20  */
21 #include "client.h"
22 #include "class.h"
23 #include "ircd.h"
24 #include "ircd_reply.h"
25 #include "list.h"
26 #include "numeric.h"
27 #include "s_conf.h"
28 #include "s_debug.h"
29 #include "send.h"
30 #include "struct.h"
31
32 #include <assert.h>
33
34 #define BAD_PING                ((unsigned int)-2)
35
36 unsigned int client_get_ping(const struct Client* acptr)
37 {
38   unsigned int     ping = 0;
39   unsigned int     tmp;
40   struct ConfItem* aconf;
41   struct SLink*    link;
42
43   for (link = acptr->confs; link; link = link->next) {
44     aconf = link->value.aconf;
45     if (aconf->status & (CONF_CLIENT | CONF_SERVER)) {
46       tmp = get_conf_ping(aconf);
47       if ((tmp != BAD_PING) && ((ping > tmp) || !ping))
48         ping = tmp;
49     }
50   }
51   if (0 == ping)
52     ping = PINGFREQUENCY;
53
54   Debug((DEBUG_DEBUG, "Client %s Ping %d", acptr->name, ping));
55   return (ping);
56 }
57
58 #if 0
59 #define BAD_CONF_CLASS          ((unsigned int)-1)
60 #define BAD_CLIENT_CLASS        ((unsigned int)-3)
61
62 unsigned int get_conf_class(struct ConfItem *aconf)
63 {
64   if ((aconf) && (aconf->confClass))
65     return (ConfClass(aconf));
66
67   Debug((DEBUG_DEBUG, "No Class For %s", (aconf) ? aconf->name : "*No Conf*"));
68
69   return (BAD_CONF_CLASS);
70
71 }
72
73 static unsigned int get_conf_ping(struct ConfItem *aconf)
74 {
75   if ((aconf) && (aconf->confClass))
76     return (ConfPingFreq(aconf));
77
78   Debug((DEBUG_DEBUG, "No Ping For %s", (aconf) ? aconf->name : "*No Conf*"));
79
80   return (BAD_PING);
81 }
82
83 unsigned int get_client_class(struct Client *acptr)
84 {
85   struct SLink *tmp;
86   struct ConfClass *cl;
87   unsigned int retc = BAD_CLIENT_CLASS;
88
89   if (acptr && !IsMe(acptr) && (acptr->confs))
90     for (tmp = acptr->confs; tmp; tmp = tmp->next)
91     {
92       if (!tmp->value.aconf || !(cl = tmp->value.aconf->confClass))
93         continue;
94       if (ConClass(cl) > retc || retc == BAD_CLIENT_CLASS)
95         retc = ConClass(cl);
96     }
97
98   Debug((DEBUG_DEBUG, "Returning Class %d For %s", retc, acptr->name));
99
100   return (retc);
101 }
102 unsigned int get_con_freq(struct ConfClass * clptr)
103 {
104   if (clptr)
105     return (ConFreq(clptr));
106   else
107     return (CONNECTFREQUENCY);
108 }
109
110 /*
111  * When adding a class, check to see if it is already present first.
112  * if so, then update the information for that class, rather than create
113  * a new entry for it and later delete the old entry.
114  * if no present entry is found, then create a new one and add it in
115  * immeadiately after the first one (class 0).
116  */
117 void add_class(unsigned int conClass, unsigned int ping, unsigned int confreq,
118     unsigned int maxli, unsigned int sendq)
119 {
120   struct ConfClass *t, *p;
121
122   t = find_class(conClass);
123   if ((t == classes) && (conClass != 0))
124   {
125     p = (struct ConfClass *) make_class();
126     NextClass(p) = NextClass(t);
127     NextClass(t) = p;
128   }
129   else
130     p = t;
131   Debug((DEBUG_DEBUG, "Add Class %u: p %p t %p - cf: %u pf: %u ml: %u sq: %d",
132       conClass, p, t, confreq, ping, maxli, sendq));
133   ConClass(p) = conClass;
134   ConFreq(p) = confreq;
135   PingFreq(p) = ping;
136   MaxLinks(p) = maxli;
137   MaxSendq(p) = (sendq > 0) ? sendq : DEFAULTMAXSENDQLENGTH;
138   if (p != t)
139     Links(p) = 0;
140 }
141
142 struct ConfClass *find_class(unsigned int cclass)
143 {
144   struct ConfClass *cltmp;
145
146   for (cltmp = FirstClass(); cltmp; cltmp = NextClass(cltmp))
147     if (ConClass(cltmp) == cclass)
148       return cltmp;
149   return classes;
150 }
151
152 void check_class(void)
153 {
154   struct ConfClass *cltmp, *cltmp2;
155
156   Debug((DEBUG_DEBUG, "Class check:"));
157
158   for (cltmp2 = cltmp = FirstClass(); cltmp; cltmp = NextClass(cltmp2))
159   {
160     Debug((DEBUG_DEBUG,
161         "Class %d : CF: %d PF: %d ML: %d LI: %d SQ: %d",
162         ConClass(cltmp), ConFreq(cltmp), PingFreq(cltmp),
163         MaxLinks(cltmp), Links(cltmp), MaxSendq(cltmp)));
164     if (IsMarkedDelete(cltmp))
165     {
166       NextClass(cltmp2) = NextClass(cltmp);
167       if (Links(cltmp) == 0)
168         free_class(cltmp);
169     }
170     else
171       cltmp2 = cltmp;
172   }
173 }
174
175 void initclass(void)
176 {
177   classes = (struct ConfClass *) make_class();
178
179   ConClass(FirstClass()) = 0;
180   ConFreq(FirstClass()) = CONNECTFREQUENCY;
181   PingFreq(FirstClass()) = PINGFREQUENCY;
182   MaxLinks(FirstClass()) = MAXIMUM_LINKS;
183   MaxSendq(FirstClass()) = DEFAULTMAXSENDQLENGTH;
184   Links(FirstClass()) = 0;
185   NextClass(FirstClass()) = NULL;
186 }
187
188 void report_classes(struct Client *sptr)
189 {
190   struct ConfClass *cltmp;
191
192   for (cltmp = FirstClass(); cltmp; cltmp = NextClass(cltmp))
193     send_reply(sptr, RPL_STATSYLINE, 'Y', ConClass(cltmp), PingFreq(cltmp),
194                ConFreq(cltmp), MaxLinks(cltmp), MaxSendq(cltmp));
195 }
196
197 unsigned int get_sendq(struct Client *cptr)
198 {
199   assert(0 != cptr);
200   assert(0 != cptr->local);
201
202   if (cptr->max_sendq)
203     return cptr->max_sendq;
204
205   else if (cptr->confs) {
206     struct SLink*     tmp;
207     struct ConfClass* cl;
208
209     for (tmp = cptr->confs; tmp; tmp = tmp->next) {
210       if (!tmp->value.aconf || !(cl = tmp->value.aconf->confClass))
211         continue;
212       if (ConClass(cl) != BAD_CLIENT_CLASS) {
213         cptr->max_sendq = MaxSendq(cl);
214         return cptr->max_sendq;
215       }
216     }
217   }
218   return DEFAULTMAXSENDQLENGTH;
219 }
220 #endif