void hchannel_mode_check(hchannel *hchan) { if (((hchan->flags & H_MAINTAIN_M) || (hchan->flags & H_QUEUE)) && !IsModerated(hchan->real_channel)) helpmod_simple_modes(hchan, CHANMODE_MODERATE, 0,0); else if (!((hchan->flags & H_MAINTAIN_M) || (hchan->flags & H_QUEUE)) && IsModerated(hchan->real_channel)) helpmod_simple_modes(hchan, 0, CHANMODE_MODERATE ,0); if (hchan->flags & H_MAINTAIN_I && !IsInviteOnly(hchan->real_channel)) helpmod_simple_modes(hchan, CHANMODE_INVITEONLY, 0,0); else if (!(hchan->flags & H_MAINTAIN_I) && IsInviteOnly(hchan->real_channel)) helpmod_simple_modes(hchan, 0, CHANMODE_INVITEONLY, 0); }
chanindex *cs_checkaccess(nick *np, const char *chan, unsigned int flags, chanindex *cip, const char *cmdname, int priv, int quiet) { reguser *rup=getreguserfromnick(np); regchan *rcp; regchanuser *rcup=NULL; unsigned long *lp; if ((flags & CA_AUTHED) && !rup) return NULL; if (!cip && !(cip=findchanindex(chan))) { if (!quiet) chanservstdmessage(np, QM_UNKNOWNCHAN, chan); return NULL; } if (!(rcp=cip->exts[chanservext])) { if (!quiet) chanservstdmessage(np, QM_UNKNOWNCHAN, cip->name->content); return NULL; } if (CIsSuspended(rcp)) { if (cs_privcheck(QPRIV_SUSPENDBYPASS, np)) { if (!quiet) chanservstdmessage(np, QM_BYPASSINGSUSPEND, cip->name->content); } else { if (!quiet) chanservstdmessage(np, QM_UNKNOWNCHAN, cip->name->content); return NULL; } } if (rcp && rup) rcup=findreguseronchannel(rcp, rup); if (!cs_privcheck(priv,np)) { if ((flags & CA_VOICEPRIV) && !(rcp && CIsVoiceAll(rcp) && !(rcup && CUIsQuiet(rcup)) && !(cip->channel && (nickbanned(np, cip->channel, 1) || IsInviteOnly(cip->channel)))) && !(rcup && CUHasVoicePriv(rcup))) { if (!quiet) chanservstdmessage(np, QM_NOACCESSONCHAN, cip->name->content, cmdname); return NULL; } if ((flags & CA_NEEDKNOWN) && !rup) { if (!quiet) chanservstdmessage(np, QM_NOACCESSONCHAN, cip->name->content, cmdname); return NULL; } if ((flags & CA_NEEDKNOWN) && (!rcup || !CUKnown(rcup))) { if (!quiet) chanservstdmessage(np, QM_NOACCESSONCHAN, cip->name->content, cmdname); return NULL; } if (((flags & CA_OPPRIV ) && !CUHasOpPriv(rcup)) || ((flags & CA_MASTERPRIV) && !CUHasMasterPriv(rcup)) || ((flags & CA_OWNERPRIV) && !CUIsOwner(rcup)) || ((flags & CA_TOPICPRIV ) && !CUHasTopicPriv(rcup))) { if (!quiet) chanservstdmessage(np, QM_NOACCESSONCHAN, cip->name->content, cmdname); return NULL; } } if ((flags & CA_ONCHANREQ) && !(cip->channel)) { if (!quiet) chanservstdmessage(np, QM_NOTONCHAN, cip->name->content); return NULL; } if (cip->channel) { lp=getnumerichandlefromchanhash(cip->channel->users, np->numeric); if ((flags & CA_ONCHANREQ) && !lp) { if (!quiet) chanservstdmessage(np, QM_NOTONCHAN, cip->name->content); return NULL; } if ((flags & CA_OPPED) && !(*lp & CUMODE_OP)) { if (!quiet) chanservstdmessage(np, QM_NOTOPPED, cip->name->content); return NULL; } if ((flags & CA_DEOPPED) && (*lp & CUMODE_OP)) { if (!quiet) chanservstdmessage(np, QM_ALREADYOPPED, cip->name->content); return NULL; } if ((flags & CA_VOICED) && !(*lp & CUMODE_VOICE)) { if (!quiet) chanservstdmessage(np, QM_NOTVOICED, cip->name->content); return NULL; } if ((flags & CA_DEVOICED) && (*lp & CUMODE_VOICE)) { if (!quiet) chanservstdmessage(np, QM_ALREADYVOICED, cip->name->content); return NULL; } if ((flags & CA_OFFCHAN) && lp) { if (!quiet) chanservstdmessage(np, QM_ALREADYONCHAN, cip->name->content); return NULL; } } return cip; }
void DoJoins(char *numeric, char *channellist, time_t timestamp) { char *currentchan; char *nextchan = channellist; struct reggedchannel *chanptr; struct user *user_ptr; int automodes; /* Right then. First up, let's see if it's 0 being joined here */ /* If so, we need to do all the work of a part (i.e. nothing) for each channel */ if (!strncmp(channellist, "0", 1)) return; user_ptr = usertablepointer[getserverindex(numeric)][getclientindex(numeric)]; while (*nextchan) { currentchan = nextchan; /* The next two blocks are going to turn currentchan into a pointer * to a well-formed string. * nextchan will point to the first char of the next channel name, if any * or NULL if this is the last one */ for (; *nextchan != ',' && *nextchan != '\0'; nextchan++); /* Look for the next comma, or end of list */ /* If we stopped on a comma, change to a NUL and advance nextchan * Otherwise, it was a NUL already, and we leave nextchan there so * the loop will stop next time round */ if (*nextchan == ',') { *nextchan = '\0'; nextchan++; } chanptr = GetChannelPointer(currentchan); if (chanptr == NULL) /* It's not a channel we care about, carry on with the next one */ continue; if (IsSuspended(chanptr)) /* Same as above, we dont really care about this channel */ continue; /* Check the timestamp */ if (timestamp > 0) SyncTimestamp(chanptr, timestamp); if (chanptr->welcome) NoticeToUser(user_ptr, "[%s] %s", chanptr->channelname, chanptr->welcome); automodes = AutoModes(numeric, currentchan); /* Update lastused timestamp on channel if user is known on it. */ if (automodes > 0) { chanptr->lastused = time(NULL); } switch (automodes) { case AUTOMODE_NOAUTOFLAGS: /* User is known, but shouldnt have voice nor op automatically. */ /* Do the same as for AUTOMODE_NOTHING (it could be a voice user). */ case AUTOMODE_NOTHING: /* It's a registered channel, which the user has no modes on */ /* We need to deop them if it's a create */ /* If the channel is inviteonly and it's a create, */ /* then kick their ass if they're unknown. */ /* We rely on the channel to be +i at all times after a createa */ /* if we have inviteonly set as chanflag. */ if (timestamp > 0) { if (!IsInviteOnly(chanptr)) { /* Channel is a normal channel */ DeopUser(chanptr, numeric); } else { /* Channel is invite only. */ if (automodes == AUTOMODE_NOAUTOFLAGS) { DeopUser(chanptr, numeric); /* User has flags, so shouldnt be kicked. */ } else { /* Must be a AUTOMODE_NOTHING, so no flags, and therefore not known on the channel. */ KickUser(chanptr, user_ptr->numeric, "Channel is invite only"); } } } break; case AUTOMODE_OP: /* It's a registered channel, which the user has ops on */ /* We need to op them if and only if it's NOT a create */ if (timestamp == 0) OpUser(chanptr, numeric); else CheckJoined(chanptr); break; case AUTOMODE_VOICE: /* It's a registered channel, the user has autovoice */ /* If it's a create, deop-and-voice, * if it's a join, just voice */ if (timestamp == 0) { VoiceUser(chanptr, numeric); } else { CheckJoined(chanptr); VoiceAndDeopUser(chanptr, numeric); } break; default: /* It's an unregistered channel, do nothing */ /* Note that with the continue above we shouldn't get here any more */ break; } } }