]> git.netwichtig.de Git - user/henk/code/inspircd.git/blob - src/users.cpp
493cbbade5d893584a17dd3b163b15b451b7bafd
[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 void userrec::CloseSocket()
63 {
64         shutdown(this->fd);
65         close(this->fd);
66 }
67  
68 char* userrec::GetFullHost()
69 {
70         snprintf(result,MAXBUF,"%s!%s@%s",nick,ident,dhost);
71         return result;
72 }
73
74 int userrec::ReadData(void* buffer, size_t size)
75 {
76         if (this->fd > -1)
77         {
78                 return read(this->fd, buffer, size)
79         }
80         else return 0;
81 }
82
83
84 char* userrec::GetFullRealHost()
85 {
86         snprintf(result,MAXBUF,"%s!%s@%s",nick,ident,host);
87         return result;
88 }
89
90 bool userrec::IsInvited(char* channel)
91 {
92         for (InvitedList::iterator i = invites.begin(); i != invites.end(); i++)
93         {
94                 if (i->channel) {
95                         if (!strcasecmp(i->channel,channel))
96                         {
97                                 return true;
98                         }
99                 }
100         }
101         return false;
102 }
103
104 InvitedList* userrec::GetInviteList()
105 {
106         return &invites;
107 }
108
109 void userrec::InviteTo(char* channel)
110 {
111         Invited i;
112         strlcpy(i.channel,channel,CHANMAX);
113         invites.push_back(i);
114 }
115
116 void userrec::RemoveInvite(char* channel)
117 {
118         log(DEBUG,"Removing invites");
119         if (channel)
120         {
121                 if (invites.size())
122                 {
123                         for (InvitedList::iterator i = invites.begin(); i != invites.end(); i++)
124                         {
125                                 if (i->channel)
126                                 {
127                                         if (!strcasecmp(i->channel,channel))
128                                         {
129                                                 invites.erase(i);
130                                                 return;
131                                         }
132                                 }
133                         }
134                 }
135         }
136 }
137
138 bool userrec::HasPermission(char* command)
139 {
140         char TypeName[MAXBUF],Classes[MAXBUF],ClassName[MAXBUF],CommandList[MAXBUF];
141         char* mycmd;
142         char* savept;
143         char* savept2;
144         
145         // are they even an oper at all?
146         if (strchr(this->modes,'o'))
147         {
148                 log(DEBUG,"*** HasPermission: %s is an oper",this->nick);
149                 for (int j =0; j < ConfValueEnum("type",&config_f); j++)
150                 {
151                         ConfValue("type","name",j,TypeName,&config_f);
152                         if (!strcmp(TypeName,this->oper))
153                         {
154                                 log(DEBUG,"*** HasPermission: %s is an oper of type '%s'",this->nick,this->oper);
155                                 ConfValue("type","classes",j,Classes,&config_f);
156                                 char* myclass = strtok_r(Classes," ",&savept);
157                                 while (myclass)
158                                 {
159                                         log(DEBUG,"*** HasPermission: checking classtype '%s'",myclass);
160                                         for (int k =0; k < ConfValueEnum("class",&config_f); k++)
161                                         {
162                                                 ConfValue("class","name",k,ClassName,&config_f);
163                                                 if (!strcmp(ClassName,myclass))
164                                                 {
165                                                         ConfValue("class","commands",k,CommandList,&config_f);
166                                                         log(DEBUG,"*** HasPermission: found class named %s with commands: '%s'",ClassName,CommandList);
167                                                         
168                                                         
169                                                         mycmd = strtok_r(CommandList," ",&savept2);
170                                                         while (mycmd)
171                                                         {
172                                                                 if (!strcasecmp(mycmd,command))
173                                                                 {
174                                                                         log(DEBUG,"*** Command %s found, returning true",command);
175                                                                         return true;
176                                                                 }
177                                                                 mycmd = strtok_r(NULL," ",&savept2);
178                                                         }
179                                                 }
180                                         }
181                                         myclass = strtok_r(NULL," ",&savept);
182                                 }
183                         }
184                 }
185         }
186         return false;
187 }
188
189
190 bool userrec::AddBuffer(std::string a)
191 {
192         std::string b = "";
193         for (int i = 0; i < a.length(); i++)
194                 if ((a[i] != '\r') && (a[i] != '\0') && (a[i] != 7))
195                         b = b + a[i];
196         std::stringstream stream(recvq);
197         stream << b;
198         recvq = stream.str();
199         int i = 0;
200         // count the size of the first line in the buffer.
201         while (i < recvq.length())
202         {
203                 if (recvq[i++] == '\n')
204                         break;
205         }
206         if (recvq.length() > this->recvqmax)
207         {
208                 this->SetWriteError("RecvQ exceeded");
209                 WriteOpers("*** User %s RecvQ of %d exceeds connect class maximum of %d",this->nick,recvq.length(),this->recvqmax);
210         }
211         // return false if we've had more than 600 characters WITHOUT
212         // a carriage return (this is BAD, drop the socket)
213         return (i < 600);
214 }
215
216 bool userrec::BufferIsReady()
217 {
218         for (int i = 0; i < recvq.length(); i++)
219                 if (recvq[i] == '\n')
220                         return true;
221         return false;
222 }
223
224 void userrec::ClearBuffer()
225 {
226         recvq = "";
227 }
228
229 std::string userrec::GetBuffer()
230 {
231         if (recvq == "")
232                 return "";
233         char* line = (char*)recvq.c_str();
234         std::string ret = "";
235         while ((*line != '\n') && (strlen(line)))
236         {
237                 ret = ret + *line;
238                 line++;
239         }
240         if ((*line == '\n') || (*line == '\r'))
241                 line++;
242         recvq = line;
243         return ret;
244 }
245
246 void userrec::AddWriteBuf(std::string data)
247 {
248         if (this->GetWriteError() != "")
249                 return;
250         if (sendq.length() + data.length() > this->sendqmax)
251         {
252                 WriteOpers("*** User %s SendQ of %d exceeds connect class maximum of %d",this->nick,sendq.length() + data.length(),this->sendqmax);
253                 this->SetWriteError("SendQ exceeded");
254                 return;
255         }
256         std::stringstream stream;
257         stream << sendq << data;
258         sendq = stream.str();
259 }
260
261 // send AS MUCH OF THE USERS SENDQ as we are able to (might not be all of it)
262 void userrec::FlushWriteBuf()
263 {
264         if (sendq.length())
265         {
266                 char* tb = (char*)this->sendq.c_str();
267                 int n_sent = write(this->fd,tb,this->sendq.length());
268                 if (n_sent == -1)
269                 {
270                         this->SetWriteError(strerror(errno));
271                 }
272                 else
273                 {
274                         // advance the queue
275                         tb += n_sent;
276                         this->sendq = tb;
277                         // update the user's stats counters
278                         this->bytes_out += n_sent;
279                         this->cmds_out++;
280                 }
281         }
282 }
283
284 void userrec::SetWriteError(std::string error)
285 {
286         log(DEBUG,"Setting error string for %s to '%s'",this->nick,error.c_str());
287         // don't try to set the error twice, its already set take the first string.
288         if (this->WriteError == "")
289                 this->WriteError = error;
290 }
291
292 std::string userrec::GetWriteError()
293 {
294         return this->WriteError;
295 }