2 #include "inspircd_io.h"
3 #include "inspircd_util.h"
4 #include "inspircd_config.h"
9 #include <sys/utsname.h>
14 #include <ext/hash_map>
26 #include "connection.h"
37 /* return 0 or 1 depending if users u and u2 share one or more common channels
38 * (used by QUIT, NICK etc which arent channel specific notices) */
40 int common_channels(userrec *u, userrec *u2)
47 log(DEFAULT,"*** BUG *** common_channels was given an invalid parameter");
50 for (int i = 0; i != MAXCHANS; i++)
52 for (z = 0; z != MAXCHANS; z++)
54 if ((u->chans[i].channel != NULL) && (u2->chans[z].channel != NULL))
56 if ((u->chans[i].channel == u2->chans[z].channel) && (u->chans[i].channel) && (u2->chans[z].channel) && (u->registered == 7) && (u2->registered == 7))
58 if ((c_count(u)) && (c_count(u2)))
70 void safedelete(userrec *p)
74 log(DEBUG,"deleting %s %s %s %s",p->nick,p->ident,p->dhost,p->fullname);
75 log(DEBUG,"safedelete(userrec*): pointer is safe to delete");
81 log(DEBUG,"safedelete(userrec*): unsafe pointer operation squished");
85 void safedelete(chanrec *p)
91 log(DEBUG,"safedelete(chanrec*): pointer is safe to delete");
95 log(DEBUG,"safedelete(chanrec*): unsafe pointer operation squished");
100 void tidystring(char* str)
102 // strips out double spaces before a : parameter
105 bool go_again = true;
112 while ((str[0] == ' ') && (strlen(str)>0))
119 bool noparse = false;
122 while (a < strlen(str))
124 if ((a<strlen(str)-1) && (noparse==false))
126 if ((str[a] == ' ') && (str[a+1] == ' '))
128 log(DEBUG,"Tidied extra space out of string: %s",str);
136 if ((str[a] == ' ') && (str[a+1] == ':'))
142 temp[t++] = str[a++];
145 strncpy(str,temp,MAXBUF);
149 /* chop a string down to 512 characters and preserve linefeed (irc max
156 log(DEBUG,"ERROR! Null string passed to chop()!");
160 FOREACH_MOD OnServerRaw(temp,false);
161 const char* str2 = temp.c_str();
162 sprintf(str,"%s",str2);
165 if (strlen(str) >= 512)
177 log(DEBUG,"Blocking: %d",s);
178 flags = fcntl(s, F_GETFL, 0);
179 fcntl(s, F_SETFL, flags ^ O_NONBLOCK);
182 void NonBlocking(int s)
185 log(DEBUG,"NonBlocking: %d",s);
186 flags = fcntl(s, F_GETFL, 0);
187 //fcntl(s, F_SETFL, O_NONBLOCK);
188 fcntl(s, F_SETFL, flags | O_NONBLOCK);
191 int CleanAndResolve (char *resolvedHost, const char *unresolvedHost)
193 struct hostent *hostPtr = NULL;
196 memset (resolvedHost, '\0',MAXBUF);
197 if(unresolvedHost == NULL)
199 if ((inet_aton(unresolvedHost,&addr)) == 0)
201 hostPtr = gethostbyaddr ((char *)&addr.s_addr,sizeof(addr.s_addr),AF_INET);
203 snprintf(resolvedHost,MAXBUF,"%s",hostPtr->h_name);
205 snprintf(resolvedHost,MAXBUF,"%s",unresolvedHost);
209 int c_count(userrec* u)
212 for (int i =0; i != MAXCHANS; i++)
213 if (u->chans[i].channel != NULL)
219 bool hasumode(userrec* user, char mode)
223 return (strchr(user->modes,mode)>0);
229 void ChangeName(userrec* user, const char* gecos)
231 strncpy(user->fullname,gecos,MAXBUF);
233 // TODO: replace these with functions:
234 // NetSendToAll - to all
235 // NetSendToCommon - to all that hold users sharing a common channel with another user
236 // NetSendToOne - to one server
237 // NetSendToAllExcept - send to all but one
241 snprintf(buffer,MAXBUF,"a %s :%s",user->nick,gecos);
242 NetSendToAll(buffer);
245 void ChangeDisplayedHost(userrec* user, const char* host)
247 strncpy(user->dhost,host,160);
249 snprintf(buffer,MAXBUF,"b %s %s",user->nick,host);
250 NetSendToAll(buffer);
253 /* verify that a user's ident and nickname is valid */
255 int isident(const char* n)
267 for (int i = 0; i != strlen(n); i++)
269 if ((n[i] < 33) || (n[i] > 125))
273 /* can't occur ANYWHERE in an Ident! */
274 if (strchr("<>,./?:;@'~#=+()*&%$£ \"!",n[i]))
283 int isnick(const char* n)
295 if (strlen(n) > NICKMAX-1)
299 for (int i = 0; i != strlen(n); i++)
301 if ((n[i] < 33) || (n[i] > 125))
305 /* can't occur ANYWHERE in a nickname! */
306 if (strchr("<>,./?:;@'~#=+()*&%$£ \"!",n[i]))
310 /* can't occur as the first char of a nickname... */
311 if ((strchr("0123456789",n[i])) && (!i))
319 /* returns the status character for a given user on a channel, e.g. @ for op,
320 * % for halfop etc. If the user has several modes set, the highest mode
321 * the user has must be returned. */
323 char* cmode(userrec *user, chanrec *chan)
325 if ((!user) || (!chan))
327 log(DEFAULT,"*** BUG *** cmode was given an invalid parameter");
332 for (int i = 0; i != MAXCHANS; i++)
334 if ((user->chans[i].channel == chan) && (chan != NULL))
336 if ((user->chans[i].uc_modes & UCMODE_OP) > 0)
340 if ((user->chans[i].uc_modes & UCMODE_HOP) > 0)
344 if ((user->chans[i].uc_modes & UCMODE_VOICE) > 0)
353 /* returns the status value for a given user on a channel, e.g. STATUS_OP for
354 * op, STATUS_VOICE for voice etc. If the user has several modes set, the
355 * highest mode the user has must be returned. */
357 int cstatus(userrec *user, chanrec *chan)
359 if ((!chan) || (!user))
361 log(DEFAULT,"*** BUG *** cstatus was given an invalid parameter");
365 for (int i = 0; i != MAXCHANS; i++)
367 if ((user->chans[i].channel == chan) && (chan != NULL))
369 if ((user->chans[i].uc_modes & UCMODE_OP) > 0)
373 if ((user->chans[i].uc_modes & UCMODE_HOP) > 0)
377 if ((user->chans[i].uc_modes & UCMODE_VOICE) > 0)
381 return STATUS_NORMAL;
386 /* returns 1 if user u has channel c in their record, 0 if not */
388 int has_channel(userrec *u, chanrec *c)
392 log(DEFAULT,"*** BUG *** has_channel was given an invalid parameter");
395 for (int i =0; i != MAXCHANS; i++)
397 if (u->chans[i].channel == c)