mIRCForumlari - mIRC ve IRC Kullanıcılarının Paylaşım Platformu
  https://www.sosyalchat.com/


SohbetG.Com

Kullanıcı Etiket Listesi

Yeni Konu aç Cevapla
 
Seçenekler
Alt 16 Ocak 2023, 09:52   #1
Çevrimdışı
Üyelik tarihi: 07 Aralık 2022
Konular: 21281
Mesajlar: 24.385
Nerden: İstanbul
Cinsiyet: Erkek
Web Site: TRmIRC.Net
IRC Sunucu: IRC.TRmIRC.Net
Alınan Beğeni: 3914
Beğendikleri: 7042
@RahmetLi
Ruh Hali : : Olu Gibi
Standart Yuzukchat.Net IRC(d) Dosyaları

Kod : Kodu kopyalamak için üzerine çift tıklayın!

/* Routines to check validity of JOINs and mode changes. * * IRC Services is copyright (c) 1996-2005 Andrew Church. * E-mail: <achurch@achurch.org> * Parts written by Andrew Kempe and others. * This program is free but copyrighted software; see the file COPYING for * details. */ #include "services.h" #include "modules.h" #include "language.h" #include "timeout.h" #include "modules/nickserv/nickserv.h" #include "modules/operserv/operserv.h" #include "chanserv.h" #include "cs-local.h" /*************************************************************************/ static Module *module; static int cb_check_modes = -1; static int cb_check_chan_user_modes = -1; static int cb_check_kick = -1; static void local_set_cumodes(Channel *c, char plusminus, int32 modes, struct c_userlist *cu); /*************************************************************************/ /*************************************************************************/ /* Check the current modes on a channel; if they conflict with a mode lock, * fix them. */ void check_modes(Channel *c) { static int in_check_modes = 0; ChannelInfo *ci; char newmode[3]; int flag; if (!c || c->bouncy_modes) return; if (!NoBouncyModes) { /* Check for mode bouncing */ if (c->server_modecount >= 3 && c->chanserv_modecount >= 3) { wallops(NULL, "Warning: unable to set modes on channel %s. " "Are your servers configured correctly?", c->name); module_log("Bouncy modes on channel %s", c->name); c->bouncy_modes = 1; return; } if (c->chanserv_modetime != time(NULL)) { c->chanserv_modecount = 0; c->chanserv_modetime = time(NULL); } c->chanserv_modecount++; } ci = c->ci; if (!ci) { /* Services _always_ knows who should be +r. If a channel tries to be * +r and is not registered, send mode -r. This will compensate for * servers that are split when mode -r is initially sent and then try * to set +r when they rejoin. -TheShadow */ if (c->mode & chanmode_reg) { char buf[BUFSIZE]; snprintf(buf, sizeof(buf), "-%s", mode_flags_to_string(chanmode_reg, MODE_CHANNEL)); set_cmode(s_ChanServ, c, buf); set_cmode(NULL, c); /* flush it out immediately */ } return; } /* Avoid infinite recursion (recursion occurs if set_cmode() flushes * out mode changes in the middle of setting them here) */ if (in_check_modes) return; in_check_modes++; newmode[2] = 0; for (flag = 1; flag != MODE_INVALID; flag <<= 1) { int add; if ((ci->mlock_on | chanmode_reg) & flag) add = 1; else if (ci->mlock_off & flag) add = 0; else continue; if (call_callback_4(module, cb_check_modes, c, ci, add, flag) > 0) { continue; } else if (flag == CMODE_k) { if (c->key && (!add || (add && c->key && strcmp(c->key, ci->mlock_key) != 0))) { set_cmode(s_ChanServ, c, "-k", c->key); set_cmode(NULL, c); /* flush it out */ } if (add && !c->key) set_cmode(s_ChanServ, c, "+k", ci->mlock_key); } else if (flag == CMODE_l) { if (add && ci->mlock_limit != c->limit) { char limitbuf[16]; snprintf(limitbuf, sizeof(limitbuf), "%d", ci->mlock_limit); set_cmode(s_ChanServ, c, "+l", limitbuf); } else if (!add && c->limit != 0) { set_cmode(s_ChanServ, c, "-l"); } } else if (add ^ !!(c->mode & flag)) { newmode[0] = add ? '+' : '-'; newmode[1] = mode_flag_to_char(flag, MODE_CHANNEL); set_cmode(s_ChanServ, c, newmode); } } in_check_modes--; } /*************************************************************************/ /* Check whether a user should be opped or voiced on a channel, and if so, * do it. Updates the channel's last used time if the user is opped. * `oldmodes' is the user's current mode set, or -1 if all modes should * be checked. `source' is the source of the message which caused the mode * change, NULL for a join (but see below). Also sets MI_CHANOWNER modes * for channel founder or identified users. * * Note that this function may be called with an empty `source' (i.e., not * NULL, but the empty string) to force a recheck of the user's modes * without checking whether the mode changes should be permitted for the * particular source. */ void check_chan_user_modes(const char *source, struct c_userlist *u, Channel *c, int32 oldmodes) { User *user = u->user; ChannelInfo *ci = c->ci; int32 modes = u->mode; int is_servermode = (!source || strchr(source, '.') != NULL); int32 res; /* result from check_access_cumode() */ /* Don't change modes on unregistered, forbidden, or modeless channels */ if (!ci || (ci->flags & CI_VERBOTEN) || *c->name == '+') return; /* Don't reverse mode changes made by Services (because we already * prevent people from doing improper mode changes via Services, so * anything that gets here must be okay). */ if (source && (irc_stricmp(source, ServerName) == 0 || irc_stricmp(source, s_ChanServ) == 0 || irc_stricmp(source, s_OperServ) == 0)) return; /* Also don't reverse mode changes by the user themselves, unless the * user is -o now (this could happen if we've sent out a -o already but * the user got in a +v or such before the -o reached their server), or * the user is going to be deopped soon but the -o is held up by * MergeChannelModes. * * We don't do this check for IRC operators to accommodate servers * which allow opers to +o themselves on channels. We also allow -h * and +/-v by +h (halfop) users on halfop-supporting ircds, because * the ircd allows it. */ if (source && !is_oper(user) && irc_stricmp(source, user->nick) == 0) { if (!(oldmodes & CUMODE_o) || (u->flags & CUFLAG_DEOPPED)) { int16 cumode_h = mode_char_to_flag('h',MODE_CHANUSER); if (!((oldmodes & cumode_h) && !((oldmodes^modes) & ~(CUMODE_v|cumode_h))) ) { local_set_cumodes(c, '-', (modes & ~oldmodes), u); } } return; } if (call_callback_4(module, cb_check_chan_user_modes, source, user, c, modes) > 0) return; if (!stricmp(c->name, "#Help") && check_access(user, ci, CA_AUTOOP) && !is_oper(user)) { send_cmd(s_NickServ, "chghost %s Helpdesk.Yuzukchat.Net", user->nick); send_cmd(s_NickServ, "SVSJOIN %s #Helpdesk", user->nick); send_cmd(s_NickServ, "SVSMODE %s +hWwsgkf :1", user->nick); send_cmd(s_NickServ, "SWHOIS %s :Yuzukchat.Net Helpdesk Görevlisi", user->nick); } if (!stricmp(c->name, "#+d") && check_access(user, ci, CA_AUTOOP)) { send_cmd(s_NickServ, "SVSMODE %s +pD :1", user->nick); } if (!stricmp(c->name, "#Yuzukchat") && check_access(user, ci, CA_AUTOOP)) { send_cmd(s_NickServ, "SVSJOIN %s #Global", user->nick); } if (!stricmp(c->name, "#Zurna") && check_access(user, ci, CA_AUTOOP)) { send_cmd(s_NickServ, "SVSJOIN %s #Global", user->nick); } if (!stricmp(c->name, "#istanbul") && check_access(user, ci, CA_AUTOOP)) { send_cmd(s_NickServ, "SVSJOIN %s #Global", user->nick); } if (!stricmp(c->name, "#Sohbet") && check_access(user, ci, CA_AUTOOP)) { send_cmd(s_NickServ, "SVSJOIN %s #Global", user->nick); } if (!stricmp(c->name, "#Muhabbet") && check_access(user, ci, CA_AUTOOP)) { send_cmd(s_NickServ, "SVSJOIN %s #Global", user->nick); } if (!stricmp(c->name, "#DiyaLog") && check_access(user, ci, CA_AUTOOP)) { send_cmd(s_NickServ, "SVSJOIN %s #Global", user->nick); } if (!stricmp(c->name, "#izmir") && check_access(user, ci, CA_AUTOOP)) { send_cmd(s_NickServ, "SVSJOIN %s #Global", user->nick); } if (!stricmp(c->name, "#ankara") && check_access(user, ci, CA_AUTOOP)) { send_cmd(s_NickServ, "SVSJOIN %s #Global", user->nick); } if (!stricmp(c->name, "#Game") && check_access(user, ci, CA_AUTOOP)) { send_cmd(s_NickServ, "SVSJOIN %s #GameOP", user->nick); } if (!stricmp(c->name, "#Radio") && check_access(user, ci, CA_AUTOOP)) { send_cmd(s_NickServ, "SVSJOIN %s #DJ", user->nick); } /* Check early for server auto-ops */ if ((modes & CUMODE_o) && !(ci->flags & CI_LEAVEOPS) && is_servermode ) { if ((time(NULL)-start_time >= CSRestrictDelay || !check_access_if_idented(user, ci, CA_AUTOOP)) && !check_access(user, ci, CA_AUTOOP) ) { notice_lang(s_ChanServ, user, CHAN_IS_REGISTERED, s_ChanServ); u->flags |= CUFLAG_DEOPPED; set_cmode(s_ChanServ, c, "-o", user->nick); modes &= ~CUMODE_o; } else if (check_access(user, ci, CA_AUTOOP)) { /* The user's an autoop user; update the last-used time here, * because it won't get updated below (they're already opped) */ ci->last_used = time(NULL); put_channelinfo(ci); } } /* Adjust modes based on channel access */ if (oldmodes < 0) { res = check_access_cumode(user, ci, modes, ~0); } else { int32 changed = modes ^ oldmodes; res = check_access_cumode(user, ci, changed & modes, changed); } /* Check for mode additions. Only check if join or server mode change, * unless ENFORCE is set */ /* Note: modes to add = changed modes & off new-modes = res & ~modes */ if ((res & ~modes) && (oldmodes < 0 || is_servermode || (ci->flags & CI_ENFORCE)) ) { local_set_cumodes(c, '+', res & ~modes, u); if ((res & ~modes) & CUMODE_o) { ci->last_used = time(NULL); put_channelinfo(ci); } } /* Don't subtract modes from opers or Services admins */ if (is_oper(user) || is_services_admin(user)) return; /* Check for mode subtractions */ if (res & modes) local_set_cumodes(c, '-', res & modes, u); } /*************************************************************************/ /* List of channels currently inhabited */ typedef struct csinhabitdata_ CSInhabitData; struct csinhabitdata_ { CSInhabitData *next, *prev; char chan[CHANMAX]; Timeout *to; }; static CSInhabitData *inhabit_list = NULL; /* Tiny helper routine to get ChanServ out of a channel after it went in. */ static void timeout_leave(Timeout *to) { CSInhabitData *data = to->data; send_cmd(s_ChanServ, "PART %s", data->chan); LIST_REMOVE(data, inhabit_list); free(data); } /* Check whether a user is permitted to be on a channel. If so, return 0; * else, kickban the user with an appropriate message (could be either * AKICK or restricted access) and return 1. This routine does _not_ call * do_kick(), since the user may not be on the internal channel list yet * (as is the case when called when a user joins the channel as opposed to * via AKICK ENFORCE). */ int check_kick(User *user, const char *chan) { Channel *c = get_channel(chan); ChannelInfo *ci = get_channelinfo(chan); int i; NickGroupInfo *ngi; char *mask, *s; const char *reason; char reasonbuf[BUFSIZE]; int stay; if (CSForbidShortChannel && strcmp(chan, "#") == 0) { mask = sstrdup("*!*@*"); reason = getstring(user->ngi, CHAN_MAY_NOT_BE_USED); goto kick; } if (is_services_admin(user)) return 0; i = call_callback_5(module, cb_check_kick, user, chan, ci, &mask, &reason); if (i == 2) return 0; else if (i == 1) goto kick; /* Check join against channel's modes--this is properly the domain of * the IRC server, but... */ if (c) { if ((c->mode & chanmode_opersonly) && !is_oper(user)) { mask = create_mask(user, 1); reason = getstring(user->ngi, CHAN_NOT_ALLOWED_TO_JOIN); goto kick; } } if (!ci) { if (CSRegisteredOnly && !is_oper(user)) { mask = sstrdup("*!*@*"); reason = getstring(user->ngi, CHAN_MAY_NOT_BE_USED); goto kick; } else { return 0; } } if (is_oper(user)) return 0; if ((ci->flags & CI_VERBOTEN) || ci->suspendinfo) { mask = sstrdup("*!*@*"); reason = getstring(user->ngi, CHAN_MAY_NOT_BE_USED); goto kick; } if (ci->mlock_on & chanmode_opersonly) { /* We already know they're not an oper, so kick them off */ mask = create_mask(user, 1); reason = getstring(user->ngi, CHAN_NOT_ALLOWED_TO_JOIN); goto kick; } if ((ci->mlock_on & chanmode_regonly) && !user_identified(user)) { /* User must have usermode_reg flags, i.e. be using a registered * nick and have identified, in order to join a chanmode_regonly * channel */ mask = create_mask(user, 1); reason = getstring(user->ngi, CHAN_NOT_ALLOWED_TO_JOIN); goto kick; } if (user_recognized(user)) ngi = user->ngi; else ngi = NULL; ARRAY_FOREACH (i, ci->akick) { if (!ci->akick[i].mask) continue; if (match_usermask(ci->akick[i].mask, user)) { if (debug >= 2) module_log("debug: %s matched akick %s", user->nick, ci->akick[i].mask); mask = sstrdup(ci->akick[i].mask); reason = ci->akick[i].reason ? ci->akick[i].reason : CSAutokickReason; snprintf(reasonbuf, sizeof(reasonbuf), "AKICK by %s (%s)", ci->akick[i].who, reason); reason = reasonbuf; time(&ci->akick[i].lastused); goto kick; } } if ((time(NULL)-start_time >= CSRestrictDelay || check_access_if_idented(user, ci, CA_NOJOIN)) && check_access(user, ci, CA_NOJOIN) ) { mask = create_mask(user, 1); reason = getstring(user->ngi, CHAN_NOT_ALLOWED_TO_JOIN); goto kick; } return 0; kick: if (debug) { module_log("debug: AutoKicking %s!%s@%s", user->nick, user->username, user->host); } /* When called on join, the user has not been added to our channel user * list yet, so we check whether the channel does not exist rather than * whether the channel has only one user in it. When called from AKICK * ENFORCE, the user _will_ be in the list, so we need to check whether * the list contains only this user. Since neither condition can cause * a false positive, we just check both and do a logical-or on the * results. */ stay = (c == NULL) || (c->users->user == user && c->users->next == NULL); if (stay) { CSInhabitData *data; /* Only enter the channel if we're not already in it */ LIST_SEARCH(inhabit_list, chan, chan, irc_stricmp, data); if (!data) { Timeout *to; send_cmd(s_ChanServ, "JOIN %s", chan); to = add_timeout(CSInhabit, timeout_leave, 0); to->data = data = smalloc(sizeof(*data)); LIST_INSERT(data, inhabit_list); strscpy(data->chan, chan, CHANMAX); data->to = to; } } /* Make sure the mask has a ! in it */ if (!(s = strchr(mask, '!')) || s > strchr(mask, '@')) { int len = strlen(mask); mask = srealloc(mask, len+3); memmove(mask+2, mask, len+1); mask[0] = '*'; mask[1] = '!'; } /* Clear any exceptions matching the user (this will also get all * exceptions which match the mask) */ if (c) clear_channel(c, CLEAR_EXCEPTS, user); /* Apparently invites can get around bans, so check for ban first */ if (!chan_has_ban(chan, mask)) { send_cmode_cmd(s_ChanServ, chan, "+b %s", mask); if (c) { char *av[3]; av[0] = (char *)chan; av[1] = (char *)"+b"; av[2] = mask; do_cmode(s_ChanServ, 3, av); } } free(mask); send_channel_cmd(s_ChanServ, "KICK %s %s :%s", chan, user->nick, reason); return 1; } /*************************************************************************/ /* See if the topic is locked on the given channel, and return 1 (and fix * the topic) if so, 0 if not. */ int check_topiclock(Channel *c, time_t topic_time) { ChannelInfo *ci = c->ci; if (!ci || !(ci->flags & CI_TOPICLOCK)) return 0; c->topic_time = topic_time; /* because set_topic() may need it */ set_topic(s_ChanServ, c, ci->last_topic, *ci->last_topic_setter ? ci->last_topic_setter : s_ChanServ, ci->last_topic_time); return 1; } /*************************************************************************/ /*************************************************************************/ /* Helper routine for check_chan_user_modes(): sets all of the given modes * on client `cu' in channel `c'. */ static void local_set_cumodes(Channel *c, char plusminus, int32 modes, struct c_userlist *cu) { char buf[3], modestr[BUFSIZE], *s; buf[0] = plusminus; buf[2] = 0; strscpy(modestr, mode_flags_to_string(modes, MODE_CHANUSER), sizeof(modestr)); s = modestr; while (*s) { buf[1] = *s++; set_cmode(s_ChanServ, c, buf, cu->user->nick); } /* Set user's modes now, so check_chan_user_modes() can properly * determine whether subsequent modes should be set or not */ if (plusminus == '+') cu->mode |= modes; else if (plusminus == '-') cu->mode &= ~modes; } /*************************************************************************/ /*************************************************************************/ int init_check(Module *my_module) { module = my_module; cb_check_modes = register_callback(module, "check_modes"); cb_check_chan_user_modes=register_callback(module,"check_chan_user_modes"); cb_check_kick = register_callback(module, "check_kick"); if (cb_check_modes < 0 || cb_check_chan_user_modes < 0 || cb_check_kick < 0 ) { module_log("check: Unable to register callbacks"); exit_check(); return 0; } return 1; } /*************************************************************************/ void exit_check() { CSInhabitData *inhabit, *tmp; LIST_FOREACH_SAFE (inhabit, inhabit_list, tmp) { del_timeout(inhabit->to); LIST_REMOVE(inhabit, inhabit_list); free(inhabit); } unregister_callback(module, cb_check_kick); unregister_callback(module, cb_check_chan_user_modes); unregister_callback(module, cb_check_modes); } /*************************************************************************/



Kalbim Atar Cansız, Geçmez Gün Ahsız, Vahsız..
  Alıntı ile Cevapla

Cevapla
Etiketler
access, c), check, copyright, debug, eli, game, global, hem, istanbul, message, muhabbet, null, or services, org, set, sohbet, user


Konuyu Toplam 1 Üye okuyor. (0 Kayıtlı üye ve 1 Misafir)