+ agline->flags &= ~GLINE_ACTIVE;
+ agline->flags |= GLINE_DESTROYED;
+
+ if (agline->lastmod == 0) {
+ Error("gline", ERR_WARNING, "Tried to destroy gline with lastmod == 0: %s", glinetostring(agline));
+ return;
+ }
+
+ if (lastmod)
+ agline->lastmod = lastmod;
+ else if (now <= agline->lastmod)
+ agline->lastmod++;
+ else
+ agline->lastmod = now;
+
+ if (propagate)
+ gline_propagate(agline);
+
+ removegline(agline);
+}
+
+void gline_propagate(gline *agline) {
+ /* Don't propagate Ulined glines. */
+ if (agline->lastmod == 0) {
+ Error("gline", ERR_WARNING, "Tried to propagate gline with lastmod == 0: %s", glinetostring(agline));
+ return;
+ }
+
+#if SNIRCD_VERSION >= 140
+#error TODO: implement 6 parameter glines for snircd >=1.4.0
+#endif /* SNIRCD_VERSION */
+
+ if (agline->flags & GLINE_DESTROYED) {
+#if SNIRCD_VERSION < 135
+ controlwall(NO_OPER, NL_GLINES_AUTO, "Tried to destroy G-Line on '%s' however SNIRCD_VERSION is too old.", glinetostring(agline));
+#else
+ controlwall(NO_OPER, NL_GLINES_AUTO, "Destroying G-Line on '%s' lasting %s with reason '%s', created by: %s",
+ glinetostring(agline), longtoduration(agline->expire-getnettime(), 0),
+ agline->reason ? agline->reason->content : "", agline->creator->content);
+
+ irc_send("%s GL * %%-%s %lu %lu :%s\r\n", mynumeric->content,
+ glinetostring(agline), agline->expire - getnettime(),
+ agline->lastmod, agline->reason ? agline->reason->content : "");
+#endif /* SNIRCD_VERSION */
+ } else if (agline->flags & GLINE_ACTIVE) {
+ controlwall(NO_OPER, NL_GLINES_AUTO, "Activating G-Line on '%s' lasting %s created by %s with reason '%s'",
+ glinetostring(agline), longtoduration(agline->expire-getnettime(), 0),
+ agline->creator->content, agline->reason ? agline->reason->content : "");
+
+ irc_send("%s GL * +%s %lu %lu :%s\r\n", mynumeric->content,
+ glinetostring(agline), agline->expire - getnettime(),
+ agline->lastmod, agline->reason ? agline->reason->content : "");
+ } else {
+ controlwall(NO_OPER, NL_GLINES_AUTO, "Deactivating G-Line on '%s' lasting %s created by %s with reason '%s'",
+ glinetostring(agline), longtoduration(agline->expire-getnettime(), 0),
+ agline->creator->content, agline->reason ? agline->reason->content : "");
+
+ irc_send("%s GL * -%s %lu %lu :%s\r\n", mynumeric->content,
+ glinetostring(agline), agline->expire - getnettime(),
+ agline->lastmod, agline->reason ? agline->reason->content : "");
+ }
+}
+
+/* returns non-zero if the glines are exactly the same */
+int glineequal(gline *gla, gline *glb) {
+ if ((gla->flags & GLINE_BADCHAN) != (glb->flags & GLINE_BADCHAN))
+ return 0;
+
+ if ((gla->flags & GLINE_REALNAME) != (glb->flags & GLINE_REALNAME))
+ return 0;
+
+ if ((gla->flags & GLINE_IPMASK) != (glb->flags & GLINE_IPMASK))
+ return 0;
+
+ if ((!gla->nick && glb->nick) || (gla->nick && !glb->nick))
+ return 0;
+
+ if (gla->nick && ircd_strcmp(gla->nick->content, glb->nick->content) != 0)
+ return 0;
+
+ if ((!gla->user && glb->user) || (gla->user && !glb->user))
+ return 0;
+
+ if (gla->user && ircd_strcmp(gla->user->content, glb->user->content) != 0)
+ return 0;
+
+ if (gla->flags & GLINE_IPMASK) {
+ if (gla->bits != glb->bits)
+ return 0;
+
+ if (!ipmask_check(&gla->ip, &glb->ip, gla->bits))
+ return 0;
+ } else {
+ if ((!gla->host && glb->host) || (gla->host && !glb->host))
+ return 0;
+
+ if (gla->host && ircd_strcmp(gla->host->content, glb->host->content) != 0)