]> git.netwichtig.de Git - user/henk/code/inspircd.git/blob - src/message.cpp
9b56cc8ca4e65c4012396a3fe181fe7de5e21fab
[user/henk/code/inspircd.git] / src / message.cpp
1 /*       +------------------------------------+
2  *       | Inspire Internet Relay Chat Daemon |
3  *       +------------------------------------+
4  *
5  *  InspIRCd is copyright (C) 2002-2006 ChatSpike-Dev.
6  *                       E-mail:
7  *                <brain@chatspike.net>
8  *                <Craig@chatspike.net>
9  *     
10  * Written by Craig Edwards, Craig McLure, and others.
11  * This program is free but copyrighted software; see
12  *            the file COPYING for details.
13  *
14  * ---------------------------------------------------
15  */
16
17 using namespace std;
18
19 #include "inspircd_config.h"
20 #include "inspircd.h"
21 #include "configreader.h"
22 #include <unistd.h>
23 #include <fcntl.h>
24 #include <sys/errno.h>
25 #include <sys/utsname.h>
26 #include <time.h>
27 #include <string>
28 #include <ext/hash_map>
29 #include <map>
30 #include <sstream>
31 #include <vector>
32 #include <deque>
33 #include "users.h"
34 #include "ctables.h"
35 #include "globals.h"
36 #include "modules.h"
37 #include "dynamic.h"
38 #include "wildcard.h"
39 #include "commands.h"
40 #include "message.h"
41 #include "inspstring.h"
42 #include "dns.h"
43 #include "helperfuncs.h"
44
45 extern int MODCOUNT;
46 extern std::vector<Module*> modules;
47 extern std::vector<ircd_module*> factory;
48 extern time_t TIME;
49 extern ServerConfig* Config;
50
51 void Blocking(int s)
52 {
53         int flags = fcntl(s, F_GETFL, 0);
54         fcntl(s, F_SETFL, flags ^ O_NONBLOCK);
55 }
56
57 void NonBlocking(int s)
58 {
59         int flags = fcntl(s, F_GETFL, 0);
60         fcntl(s, F_SETFL, flags | O_NONBLOCK);
61 }
62
63 int c_count(userrec* u)
64 {
65         int z = 0;
66         for (std::vector<ucrec*>::const_iterator i = u->chans.begin(); i != u->chans.end(); i++)
67                 if ((*i)->channel)
68                         z++;
69         return z;
70
71 }
72
73 void ChangeName(userrec* user, const char* gecos)
74 {
75         if (user->fd > -1)
76         {
77                 int MOD_RESULT = 0;
78                 FOREACH_RESULT(I_OnChangeLocalUserGECOS,OnChangeLocalUserGECOS(user,gecos));
79                 if (MOD_RESULT)
80                         return;
81                 FOREACH_MOD(I_OnChangeName,OnChangeName(user,gecos));
82         }
83         strlcpy(user->fullname,gecos,MAXGECOS+1);
84 }
85
86 void ChangeDisplayedHost(userrec* user, const char* host)
87 {
88         if (user->fd > -1)
89         {
90                 int MOD_RESULT = 0;
91                 FOREACH_RESULT(I_OnChangeLocalUserHost,OnChangeLocalUserHost(user,host));
92                 if (MOD_RESULT)
93                         return;
94                 FOREACH_MOD(I_OnChangeHost,OnChangeHost(user,host));
95         }
96         strlcpy(user->dhost,host,63);
97         user->WriteServ("396 %s %s :is now your hidden host",user->nick,user->dhost);
98 }
99
100 /* verify that a user's ident and nickname is valid */
101
102 int isident(const char* n)
103 {
104         if (!n || !*n)
105         {
106                 return 0;
107         }
108         for (char* i = (char*)n; *i; i++)
109         {
110                 if ((*i >= 'A') && (*i <= '}'))
111                 {
112                         continue;
113                 }
114                 if (((*i >= '0') && (*i <= '9')) || (*i == '-') || (*i == '.'))
115                 {
116                         continue;
117                 }
118                 return 0;
119         }
120         return 1;
121 }
122
123
124 int isnick(const char* n)
125 {
126         if (!n || !*n)
127         {
128                 return 0;
129         }
130         int p = 0;
131         for (char* i = (char*)n; *i; i++, p++)
132         {
133                 /* "A"-"}" can occur anywhere in a nickname */
134                 if ((*i >= 'A') && (*i <= '}'))
135                 {
136                         continue;
137                 }
138                 /* "0"-"9", "-" can occur anywhere BUT the first char of a nickname */
139                 if ((((*i >= '0') && (*i <= '9')) || (*i == '-')) && (i > n))
140                 {
141                         continue;
142                 }
143                 /* invalid character! abort */
144                 return 0;
145         }
146         return (p < NICKMAX - 1);
147 }
148
149 /* returns the status character for a given user on a channel, e.g. @ for op,
150  * % for halfop etc. If the user has several modes set, the highest mode
151  * the user has must be returned. */
152
153 const char* cmode(userrec *user, chanrec *chan)
154 {
155         if ((!user) || (!chan))
156         {
157                 log(DEFAULT,"*** BUG *** cmode was given an invalid parameter");
158                 return "";
159         }
160
161         for (std::vector<ucrec*>::const_iterator i = user->chans.begin(); i != user->chans.end(); i++)
162         {
163                 if ((*i)->channel == chan)
164                 {
165                         if (((*i)->uc_modes & UCMODE_OP) > 0)
166                         {
167                                 return "@";
168                         }
169                         if (((*i)->uc_modes & UCMODE_HOP) > 0)
170                         {
171                                 return "%";
172                         }
173                         if (((*i)->uc_modes & UCMODE_VOICE) > 0)
174                         {
175                                 return "+";
176                         }
177                         return "";
178                 }
179         }
180         return "";
181 }
182
183 int cflags(userrec *user, chanrec *chan)
184 {
185         if ((!chan) || (!user))
186                 return 0;
187
188         for (std::vector<ucrec*>::const_iterator i = user->chans.begin(); i != user->chans.end(); i++)
189         {
190                 if ((*i)->channel == chan)
191                 {
192                         return (*i)->uc_modes;
193                 }
194         }
195         return 0;
196 }
197
198 /* returns the status value for a given user on a channel, e.g. STATUS_OP for
199  * op, STATUS_VOICE for voice etc. If the user has several modes set, the
200  * highest mode the user has must be returned. */
201
202 int cstatus(userrec *user, chanrec *chan)
203 {
204         if ((!chan) || (!user))
205         {
206                 log(DEFAULT,"*** BUG *** cstatus was given an invalid parameter");
207                 return 0;
208         }
209
210         if (is_uline(user->server))
211                 return STATUS_OP;
212
213         for (std::vector<ucrec*>::const_iterator i = user->chans.begin(); i != user->chans.end(); i++)
214         {
215                 if ((*i)->channel == chan)
216                 {
217                         if (((*i)->uc_modes & UCMODE_OP) > 0)
218                         {
219                                 return STATUS_OP;
220                         }
221                         if (((*i)->uc_modes & UCMODE_HOP) > 0)
222                         {
223                                 return STATUS_HOP;
224                         }
225                         if (((*i)->uc_modes & UCMODE_VOICE) > 0)
226                         {
227                                 return STATUS_VOICE;
228                         }
229                         return STATUS_NORMAL;
230                 }
231         }
232         return STATUS_NORMAL;
233 }
234
235 std::string chlist(userrec *user,userrec* source)
236 {
237         std::string list;
238         
239         if (!user || !source)
240                 return "";
241         
242         for (std::vector<ucrec*>::const_iterator i = user->chans.begin(); i != user->chans.end(); i++)
243         {
244                 ucrec* rec = *i;
245                 
246                 if(rec->channel && rec->channel->name)
247                 {       
248                         /* If the target is the same as the sender, let them see all their channels.
249                          * If the channel is NOT private/secret OR the user shares a common channel
250                          * If the user is an oper, and the <options:operspywhois> option is set.
251                          */
252                         if ((source == user) || (*source->oper && Config->OperSpyWhois) || (((!rec->channel->modes[CM_PRIVATE]) && (!rec->channel->modes[CM_SECRET])) || (rec->channel->HasUser(source))))
253                         {
254                                 list.append(cmode(user, rec->channel)).append(rec->channel->name).append(" ");
255                         }
256                 }
257         }
258         return list;
259 }