+ /* can't modify a G-line that doesn't exist, so remap to activate */
+ if (!agline && action == GLINE_MODIFY)
+ action = GLINE_ACTIVATE;
+
+ /* OK, let's figure out what other parameters we may have... */
+ switch (action) {
+ case GLINE_LOCAL_ACTIVATE: /* locally activating a G-line */
+ case GLINE_LOCAL_DEACTIVATE: /* locally deactivating a G-line */
+ if (!agline) /* no G-line to locally activate or deactivate? */
+ return send_reply(sptr, ERR_NOSUCHGLINE, mask);
+ lastmod = agline->gl_lastmod;
+ break; /* no additional parameters to manipulate */
+
+ case GLINE_ACTIVATE: /* activating a G-line */
+ case GLINE_DEACTIVATE: /* deactivating a G-line */
+ /* in either of these cases, we have at least a lastmod parameter */
+ if (parc < 4)
+ return need_more_params(sptr, "GLINE");
+ else if (parc == 4) /* lastmod only form... */
+ lastmod = atoi(parv[3]);
+ /*FALLTHROUGH*/
+ case GLINE_MODIFY: /* modifying a G-line */
+ /* convert expire and lastmod, look for lifetime and reason */
+ if (parc > 4) { /* protect against fall-through from 4-param form */
+ expire = atoi(parv[3]); /* convert expiration and lastmod */
+ expire = abs_expire(expire);
+ lastmod = atoi(parv[4]);
+
+ flags |= GLINE_EXPIRE; /* we have an expiration time update */
+
+ if (parc > 6) { /* no question, have a lifetime and reason */
+ lifetime = atoi(parv[5]);
+ reason = parv[parc - 1];
+
+ flags |= GLINE_LIFETIME | GLINE_REASON;
+ } else if (parc == 6) { /* either a lifetime or a reason */
+ if (!agline || /* gline creation, has to be the reason */
+ /* trial-convert as lifetime, and if it doesn't fully convert,
+ * it must be the reason */
+ ((lifetime = strtoul(parv[5], &tmp, 10)) && !*tmp)) {
+ lifetime = 0;
+ reason = parv[5];
+
+ flags |= GLINE_REASON; /* have a reason update */
+ } else if (lifetime)
+ flags |= GLINE_LIFETIME; /* have a lifetime update */
+ }
+ }
+ }
+
+ if (!lastmod) /* must have a lastmod parameter by now */
+ return need_more_params(sptr, "GLINE");
+
+ Debug((DEBUG_DEBUG, "I have a global G-line I am acting upon now; "
+ "target %s, mask %s, operforce %s, action %s, expire %Tu, "
+ "lastmod %Tu, lifetime %Tu, reason: %s; gline %s! (fields "
+ "present: %s %s %s)", target, mask,
+ flags & GLINE_OPERFORCE ? "YES" : "NO",
+ action == GLINE_ACTIVATE ? "+" :
+ (action == GLINE_DEACTIVATE ? "-" :
+ (action == GLINE_LOCAL_ACTIVATE ? ">" :
+ (action == GLINE_LOCAL_DEACTIVATE ? "<" : "(MODIFY)"))),
+ expire, lastmod, lifetime, reason,
+ agline ? "EXISTS" : "does not exist",
+ flags & GLINE_EXPIRE ? "expire" : "",
+ flags & GLINE_LIFETIME ? "lifetime" : "",
+ flags & GLINE_REASON ? "reason" : ""));
+
+ /* OK, at this point, we have converted all available parameters.
+ * Let's actually do the action!
+ */
+ if (agline)
+ return gline_modify(cptr, sptr, agline, action, reason, expire,
+ lastmod, lifetime, flags);
+
+ assert(action != GLINE_LOCAL_ACTIVATE);
+ assert(action != GLINE_LOCAL_DEACTIVATE);
+ assert(action != GLINE_MODIFY);
+
+ if (!expire) { /* Cannot *add* a G-line we don't have, but try hard */
+ Debug((DEBUG_DEBUG, "Propagating G-line %s for G-line we don't have",
+ action == GLINE_ACTIVATE ? "activation" : "deactivation"));
+
+ /* propagate the G-line, even though we don't have it */
+ sendcmdto_serv_butone(sptr, CMD_GLINE, cptr, "* %c%s %Tu",
+ action == GLINE_ACTIVATE ? '+' : '-',
+ mask, lastmod);
+
+ return 0;
+ }
+
+ return gline_add(cptr, sptr, mask, reason, expire, lastmod, lifetime,
+ flags | ((action == GLINE_ACTIVATE) ? GLINE_ACTIVE : 0));