Author: Kev <klmitch@mit.edu>
[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_features.h"
25 #include "ircd_reply.h"
26 #include "list.h"
27 #include "numeric.h"
28 #include "s_conf.h"
29 #include "s_debug.h"
30 #include "send.h"
31 #include "struct.h"
32
33 #include <assert.h>
34
35 #define BAD_PING                ((unsigned int)-2)
36
37 /*
38  * client_get_ping
39  * returns shortest ping time in attached server or client conf
40  * classes or PINGFREQUENCY
41  */
42 int client_get_ping(const struct Client* acptr)
43 {
44   int     ping = 0;
45   struct ConfItem* aconf;
46   struct SLink*    link;
47
48   for (link = cli_confs(acptr); link; link = link->next) {
49     aconf = link->value.aconf;
50     if (aconf->status & (CONF_CLIENT | CONF_SERVER)) {
51       int tmp = get_conf_ping(aconf);
52       if (0 < tmp && (ping > tmp || !ping))
53         ping = tmp;
54     }
55   }
56   if (0 == ping)
57     ping = PINGFREQUENCY;
58
59   Debug((DEBUG_DEBUG, "Client %s Ping %d", cli_name(acptr), ping));
60   return ping;
61 }
62
63 /*
64  * client_drop_sendq
65  * removes the client's connection from the list of connections with
66  * queued data
67  */
68 void client_drop_sendq(struct Connection* con)
69 {
70   if (con_prev_p(con)) { /* on the queued data list... */
71     if (con_next(con))
72       con_prev_p(con_next(con)) = con_prev_p(con);
73     *(con_prev_p(con)) = con_next(con);
74
75     con_next(con) = 0;
76     con_prev_p(con) = 0;
77   }
78 }
79
80 /*
81  * client_add_sendq
82  * adds the client's connection to the list of connections with
83  * queued data
84  */
85 void client_add_sendq(struct Connection* con, struct Connection** con_p)
86 {
87   if (!con_prev_p(con)) { /* not on the queued data list yet... */
88     con_prev_p(con) = con_p;
89     con_next(con) = *con_p;
90
91     if (*con_p)
92       con_prev_p(*con_p) = &(con_next(con));
93     *con_p = con;
94   }
95 }
96
97 /* client_set_privs(struct Client* client)
98  *
99  * Sets the privileges for opers.
100  */
101 void
102 client_set_privs(struct Client* client)
103 {
104   unsigned int privs = 0;
105   unsigned int antiprivs = 0;
106
107   if (!IsAnOper(client)) {
108     cli_privs(client) = 0; /* clear privilege mask */
109     return;
110   } else if (!MyConnect(client)) {
111     cli_privs(client) = ~(PRIV_SET); /* everything but set... */
112     return;
113   }
114
115   /* This sequence is temporary until the .conf is carefully rewritten */
116
117   privs |= (PRIV_WHOX | PRIV_DISPLAY);
118   if (feature_bool(FEAT_OPER_NO_CHAN_LIMIT))
119     privs |= PRIV_CHAN_LIMIT;
120   if (feature_bool(FEAT_OPER_MODE_LCHAN))
121     privs |= (PRIV_MODE_LCHAN | PRIV_LOCAL_OPMODE);
122   if (feature_bool(FEAT_OPER_WALK_THROUGH_LMODES))
123     privs |= PRIV_WALK_LCHAN;
124   if (feature_bool(FEAT_NO_OPER_DEOP_LCHAN))
125     privs |= PRIV_DEOP_LCHAN;
126   if (feature_bool(FEAT_SHOW_INVISIBLE_USERS))
127     privs |= PRIV_SHOW_INVIS;
128   if (feature_bool(FEAT_SHOW_ALL_INVISIBLE_USERS))
129     privs |= PRIV_SHOW_ALL_INVIS;
130   if (feature_bool(FEAT_UNLIMIT_OPER_QUERY))
131     privs |= PRIV_UNLIMIT_QUERY;
132   if (feature_bool(FEAT_LOCAL_KILL_ONLY))
133     antiprivs |= PRIV_KILL;
134   if (!feature_bool(FEAT_CONFIG_OPERCMDS))
135     antiprivs |= (PRIV_GLINE | PRIV_JUPE | PRIV_OPMODE | PRIV_BADCHAN);
136
137   if (IsOper(client)) {
138     privs |= (PRIV_SET | PRIV_PROPAGATE | PRIV_SEE_OPERS);
139     if (feature_bool(FEAT_OPER_KILL))
140       privs |= (PRIV_KILL | PRIV_LOCAL_KILL);
141     if (feature_bool(FEAT_OPER_REHASH))
142       privs |= PRIV_REHASH;
143     if (feature_bool(FEAT_OPER_RESTART))
144       privs |= PRIV_RESTART;
145     if (feature_bool(FEAT_OPER_DIE))
146       privs |= PRIV_DIE;
147     if (feature_bool(FEAT_OPER_GLINE))
148       privs |= PRIV_GLINE;
149     if (feature_bool(FEAT_OPER_LGLINE))
150       privs |= PRIV_LOCAL_GLINE;
151     if (feature_bool(FEAT_OPER_JUPE))
152       privs |= PRIV_JUPE;
153     if (feature_bool(FEAT_OPER_LJUPE))
154       privs |= PRIV_LOCAL_JUPE;
155     if (feature_bool(FEAT_OPER_OPMODE))
156       privs |= PRIV_OPMODE;
157     if (feature_bool(FEAT_OPER_LOPMODE))
158       privs |= PRIV_LOCAL_OPMODE;
159     if (feature_bool(FEAT_OPER_BADCHAN))
160       privs |= PRIV_BADCHAN;
161     if (feature_bool(FEAT_OPER_LBADCHAN))
162       privs |= PRIV_LOCAL_BADCHAN;
163     if (feature_bool(FEAT_OPERS_SEE_IN_SECRET_CHANNELS))
164       privs |= PRIV_SEE_CHAN;
165   } else { /* is a local operator */
166     if (feature_bool(FEAT_LOCOP_KILL))
167       privs |= PRIV_LOCAL_KILL;
168     if (feature_bool(FEAT_LOCOP_REHASH))
169       privs |= PRIV_REHASH;
170     if (feature_bool(FEAT_LOCOP_RESTART))
171       privs |= PRIV_RESTART;
172     if (feature_bool(FEAT_LOCOP_DIE))
173       privs |= PRIV_DIE;
174     if (feature_bool(FEAT_LOCOP_LGLINE))
175       privs |= PRIV_LOCAL_GLINE;
176     if (feature_bool(FEAT_LOCOP_LJUPE))
177       privs |= PRIV_LOCAL_JUPE;
178     if (feature_bool(FEAT_LOCOP_LOPMODE))
179       privs |= PRIV_LOCAL_OPMODE;
180     if (feature_bool(FEAT_LOCOP_LBADCHAN))
181       privs |= PRIV_LOCAL_BADCHAN;
182     if (feature_bool(FEAT_LOCOP_SEE_IN_SECRET_CHANNELS))
183       privs |= PRIV_SEE_CHAN;
184   }
185
186   /* This is the end of the gross section */
187
188   if (privs & PRIV_PROPAGATE)
189     privs |= PRIV_DISPLAY;
190   else
191     antiprivs |= (PRIV_KILL | PRIV_GLINE | PRIV_JUPE | PRIV_OPMODE |
192                   PRIV_BADCHAN);
193
194   cli_privs(client) = privs & ~antiprivs;
195 }