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