]> git.netwichtig.de Git - user/henk/code/inspircd.git/blob - src/users.cpp
*** empty log message ***
[user/henk/code/inspircd.git] / src / users.cpp
1 /*       +------------------------------------+
2  *       | Inspire Internet Relay Chat Daemon |
3  *       +------------------------------------+
4  *
5  *  Inspire is copyright (C) 2002-2004 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 "channels.h"
21 #include "users.h"
22 #include "inspircd.h"
23 #include <stdio.h>
24 #include "inspstring.h"
25 #include "helperfuncs.h"
26
27 extern std::stringstream config_f;
28
29 extern time_t TIME;
30
31 userrec::userrec()
32 {
33         // the PROPER way to do it, AVOID bzero at *ALL* costs
34         strcpy(nick,"");
35         strcpy(ip,"127.0.0.1");
36         timeout = 0;
37         strcpy(ident,"");
38         strcpy(host,"");
39         strcpy(dhost,"");
40         strcpy(fullname,"");
41         strcpy(modes,"");
42         strcpy(server,"");
43         strcpy(awaymsg,"");
44         strcpy(oper,"");
45         reset_due = TIME;
46         lines_in = 0;
47         fd = lastping = signon = idle_lastmsg = nping = registered = 0;
48         flood = port = bytes_in = bytes_out = cmds_in = cmds_out = 0;
49         haspassed = false;
50         dns_done = false;
51         recvq = "";
52         sendq = "";
53         strcpy(result,"");
54         for (int i = 0; i < MAXCHANS; i++)
55         {
56                 this->chans[i].channel = NULL;
57                 this->chans[i].uc_modes = 0;
58         }
59         invites.clear();
60 }
61
62
63  
64 char* userrec::GetFullHost()
65 {
66         snprintf(result,MAXBUF,"%s!%s@%s",nick,ident,dhost);
67         return result;
68 }
69
70
71 char* userrec::GetFullRealHost()
72 {
73         snprintf(result,MAXBUF,"%s!%s@%s",nick,ident,host);
74         return result;
75 }
76
77 bool userrec::IsInvited(char* channel)
78 {
79         for (InvitedList::iterator i = invites.begin(); i != invites.end(); i++)
80         {
81                 if (i->channel) {
82                         if (!strcasecmp(i->channel,channel))
83                         {
84                                 return true;
85                         }
86                 }
87         }
88         return false;
89 }
90
91 InvitedList* userrec::GetInviteList()
92 {
93         return &invites;
94 }
95
96 void userrec::InviteTo(char* channel)
97 {
98         Invited i;
99         strlcpy(i.channel,channel,CHANMAX);
100         invites.push_back(i);
101 }
102
103 void userrec::RemoveInvite(char* channel)
104 {
105         log(DEBUG,"Removing invites");
106         if (channel)
107         {
108                 if (invites.size())
109                 {
110                         for (InvitedList::iterator i = invites.begin(); i != invites.end(); i++)
111                         {
112                                 if (i->channel)
113                                 {
114                                         if (!strcasecmp(i->channel,channel))
115                                         {
116                                                 invites.erase(i);
117                                                 return;
118                                         }
119                                 }
120                         }
121                 }
122         }
123 }
124
125 bool userrec::HasPermission(char* command)
126 {
127         char TypeName[MAXBUF],Classes[MAXBUF],ClassName[MAXBUF],CommandList[MAXBUF];
128         char* mycmd;
129         char* savept;
130         char* savept2;
131         
132         // are they even an oper at all?
133         if (strchr(this->modes,'o'))
134         {
135                 log(DEBUG,"*** HasPermission: %s is an oper",this->nick);
136                 for (int j =0; j < ConfValueEnum("type",&config_f); j++)
137                 {
138                         ConfValue("type","name",j,TypeName,&config_f);
139                         if (!strcmp(TypeName,this->oper))
140                         {
141                                 log(DEBUG,"*** HasPermission: %s is an oper of type '%s'",this->nick,this->oper);
142                                 ConfValue("type","classes",j,Classes,&config_f);
143                                 char* myclass = strtok_r(Classes," ",&savept);
144                                 while (myclass)
145                                 {
146                                         log(DEBUG,"*** HasPermission: checking classtype '%s'",myclass);
147                                         for (int k =0; k < ConfValueEnum("class",&config_f); k++)
148                                         {
149                                                 ConfValue("class","name",k,ClassName,&config_f);
150                                                 if (!strcmp(ClassName,myclass))
151                                                 {
152                                                         ConfValue("class","commands",k,CommandList,&config_f);
153                                                         log(DEBUG,"*** HasPermission: found class named %s with commands: '%s'",ClassName,CommandList);
154                                                         
155                                                         
156                                                         mycmd = strtok_r(CommandList," ",&savept2);
157                                                         while (mycmd)
158                                                         {
159                                                                 if (!strcasecmp(mycmd,command))
160                                                                 {
161                                                                         log(DEBUG,"*** Command %s found, returning true",command);
162                                                                         return true;
163                                                                 }
164                                                                 mycmd = strtok_r(NULL," ",&savept2);
165                                                         }
166                                                 }
167                                         }
168                                         myclass = strtok_r(NULL," ",&savept);
169                                 }
170                         }
171                 }
172         }
173         return false;
174 }
175
176
177 bool userrec::AddBuffer(std::string a)
178 {
179         std::string b = "";
180         for (int i = 0; i < a.length(); i++)
181                 if ((a[i] != '\r') && (a[i] != '\0') && (a[i] != 7))
182                         b = b + a[i];
183         std::stringstream stream(recvq);
184         stream << b;
185         recvq = stream.str();
186         int i = 0;
187         // count the size of the first line in the buffer.
188         while (i < recvq.length())
189         {
190                 if (recvq[i++] == '\n')
191                         break;
192         }
193         if (recvq.length() > this->recvqmax)
194         {
195                 this->SetWriteError("RecvQ exceeded");
196                 WriteOpers("*** User %s RecvQ of %d exceeds connect class maximum of %d",this->nick,recvq.length(),this->recvqmax);
197         }
198         // return false if we've had more than 600 characters WITHOUT
199         // a carriage return (this is BAD, drop the socket)
200         return (i < 600);
201 }
202
203 bool userrec::BufferIsReady()
204 {
205         for (int i = 0; i < recvq.length(); i++)
206                 if (recvq[i] == '\n')
207                         return true;
208         return false;
209 }
210
211 void userrec::ClearBuffer()
212 {
213         recvq = "";
214 }
215
216 std::string userrec::GetBuffer()
217 {
218         if (recvq == "")
219                 return "";
220         char* line = (char*)recvq.c_str();
221         std::string ret = "";
222         while ((*line != '\n') && (strlen(line)))
223         {
224                 ret = ret + *line;
225                 line++;
226         }
227         if ((*line == '\n') || (*line == '\r'))
228                 line++;
229         recvq = line;
230         return ret;
231 }
232
233 void userrec::AddWriteBuf(std::string data)
234 {
235         if (this->GetWriteError() != "")
236                 return;
237         if (sendq.length() + data.length() > this->sendqmax)
238         {
239                 WriteOpers("*** User %s SendQ of %d exceeds connect class maximum of %d",this->nick,sendq.length() + data.length(),this->sendqmax);
240                 this->SetWriteError("SendQ exceeded");
241                 return;
242         }
243         std::stringstream stream;
244         stream << sendq << data;
245         sendq = stream.str();
246 }
247
248 // send AS MUCH OF THE USERS SENDQ as we are able to (might not be all of it)
249 void userrec::FlushWriteBuf()
250 {
251         if (sendq.length())
252         {
253                 char* tb = (char*)this->sendq.c_str();
254                 int n_sent = write(this->fd,tb,this->sendq.length());
255                 if (n_sent == -1)
256                 {
257                         this->SetWriteError(strerror(errno));
258                 }
259                 else
260                 {
261                         // advance the queue
262                         tb += n_sent;
263                         this->sendq = tb;
264                         // update the user's stats counters
265                         this->bytes_out += n_sent;
266                         this->cmds_out++;
267                 }
268         }
269 }
270
271 void userrec::SetWriteError(std::string error)
272 {
273         log(DEBUG,"Setting error string for %s to '%s'",this->nick,error.c_str());
274         // don't try to set the error twice, its already set take the first string.
275         if (this->WriteError == "")
276                 this->WriteError = error;
277 }
278
279 std::string userrec::GetWriteError()
280 {
281         return this->WriteError;
282 }