2 * IRC - Internet Relay Chat, ircd/gline.c
3 * Copyright (C) 1990 Jarkko Oikarinen and
4 * University of Oulu, Finland
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 1, or (at your option)
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 #include "ircd_alloc.h"
26 #include "ircd_string.h"
33 #include "sys.h" /* FALSE bleah */
37 struct Gline* GlobalGlineList = 0;
38 struct Gline* BadChanGlineList = 0;
41 struct Gline *make_gline(int is_ipmask, char *host, char *reason,
42 char *name, time_t expire)
48 if ('#' == *host || '&' == *host || '+' == *host)
49 gtype = 1; /* BAD CHANNEL GLINE */
52 agline = (struct Gline*) MyMalloc(sizeof(struct Gline)); /* alloc memory */
54 DupString(agline->host, host); /* copy vital information */
55 DupString(agline->reason, reason);
56 DupString(agline->name, name);
57 agline->expire = expire;
58 agline->gflags = GLINE_ACTIVE; /* gline is active */
60 SetGlineIsIpMask(agline);
64 agline->next = BadChanGlineList; /* link it into the list */
65 return (BadChanGlineList = agline);
68 agline->next = GlobalGlineList; /* link it into the list */
69 return (GlobalGlineList = agline);
72 struct Gline *find_gline(struct Client *cptr, struct Gline **pgline)
74 struct Gline* gline = GlobalGlineList;
75 struct Gline* prev = 0;
79 * look through all glines
81 if (gline->expire <= TStime()) {
83 * handle expired glines
85 free_gline(gline, prev);
86 gline = prev ? prev->next : GlobalGlineList;
88 break; /* gline == NULL means gline == NULL */
92 /* Does gline match? */
93 /* Added a check against the user's IP address as well -Kev */
94 if ((GlineIsIpMask(gline) ?
95 match(gline->host, ircd_ntoa((const char*) &cptr->ip)) :
96 match(gline->host, cptr->sockhost)) == 0 &&
97 match(gline->name, cptr->user->username) == 0) {
99 *pgline = prev; /* If they need it, give them the previous gline
100 entry (probably for free_gline, below) */
108 return 0; /* found no glines */
111 void free_gline(struct Gline* gline, struct Gline* prev)
115 prev->next = gline->next; /* squeeze agline out */
118 assert(0 != gline->host);
119 if ('#' == *gline->host ||
120 '&' == *gline->host ||
121 '+' == *gline->host) {
122 BadChanGlineList = gline->next;
126 GlobalGlineList = gline->next;
129 MyFree(gline->host); /* and free up the memory */
130 MyFree(gline->reason);
135 void gline_remove_expired(time_t now)
138 struct Gline* prev = 0;
140 for (gline = GlobalGlineList; gline; gline = gline->next) {
141 if (gline->expire < now) {
142 free_gline(gline, prev);
143 gline = (prev) ? prev : GlobalGlineList;
153 int bad_channel(const char* name)
155 struct Gline* agline = BadChanGlineList;
159 if ((agline->gflags & GLINE_ACTIVE) && (agline->expire > TStime()) &&
160 !mmatch(agline->host, name)) {
163 agline = agline->next;
168 void bad_channel_remove_expired(time_t now)
171 struct Gline* prev = 0;
173 for (gline = BadChanGlineList; gline; gline = gline->next) {
174 if (gline->expire < now) {
175 free_gline(gline, prev);
176 gline = (prev) ? prev : BadChanGlineList;
188 void add_gline(struct Client *sptr, int ip_mask, char *host, char *comment,
189 char *user, time_t expire, int local)
191 struct Client *acptr;
192 struct Gline *agline;
198 if ('#' == *host || '&' == *host || '+' == *host)
199 gtype = 1; /* BAD CHANNEL */
203 sendto_op_mask(SNO_GLINE,
204 "%s adding %s%s for %s@%s, expiring at " TIME_T_FMT ": %s", sptr->name,
205 local ? "local " : "",
206 gtype ? "BADCHAN" : "GLINE", user, host, expire, comment);
210 "# " TIME_T_FMT " %s adding %s %s for %s@%s, expiring at " TIME_T_FMT
211 ": %s\n", TStime(), sptr->name, local ? "local" : "global",
212 gtype ? "BADCHAN" : "GLINE", user, host, expire, comment);
214 /* this can be inserted into the conf */
216 write_log(GPATH, "%c:%s:%s:%s\n", ip_mask ? 'k' : 'K', host, comment,
220 agline = make_gline(ip_mask, host, comment, user, expire);
222 SetGlineIsLocal(agline);
229 for (fd = HighestFd; fd >= 0; --fd) {
233 if ((acptr = LocalClientArray[fd])) {
240 if (!acptr->user || strlen(acptr->sockhost) > HOSTLEN ||
241 (acptr->user->username ? strlen(acptr->user->username) : 0) > HOSTLEN)
242 continue; /* these tests right out of
243 find_kill for safety's sake */
246 if ((GlineIsIpMask(agline) ? match(agline->host, acptr->sock_ip) :
247 match(agline->host, acptr->sockhost)) == 0 &&
248 (!acptr->user->username ||
249 match(agline->name, acptr->user->username) == 0))
252 /* ok, he was the one that got G-lined */
253 sendto_one(acptr, ":%s %d %s :*** %s.", me.name,
254 ERR_YOUREBANNEDCREEP, acptr->name, agline->reason);
256 /* let the ops know about my first kill */
257 sendto_op_mask(SNO_GLINE, "G-line active for %s",
258 get_client_name(acptr, FALSE));
260 /* and get rid of him */
262 exit_client_msg(sptr->from, acptr, &me, "G-lined (%s)", agline->reason);