#include <stdlib.h>
#include <string.h>
+#define PASTWATCH 157680000 /* number of seconds in 5 years */
+
+/*
+ * If the expiration value, interpreted as an absolute timestamp, is
+ * more recent than 5 years in the past, we interpret it as an
+ * absolute timestamp; otherwise, we assume it's relative and convert
+ * it to an absolute timestamp. Either way, the output of this macro
+ * is an absolute timestamp--not guaranteed to be a *valid* timestamp,
+ * but you can't have everything in a macro ;)
+ */
+#define abs_expire(exp) \
+ ((exp) >= CurrentTime - PASTWATCH ? (exp) : (exp) + CurrentTime)
+
/*
* ms_gline - server message handler
*
struct Gline *agline = 0;
unsigned int flags = 0;
enum GlineAction action = GLINE_MODIFY;
- time_t expire_off = 0, lastmod = 0, lifetime = 0;
+ time_t expire = 0, lastmod = 0, lifetime = 0;
char *mask = parv[2], *target = parv[1], *reason = "No reason", *tmp = 0;
if (parc < 3)
if ((action == GLINE_LOCAL_ACTIVATE || action == GLINE_LOCAL_DEACTIVATE) &&
!IsMe(acptr)) {
Debug((DEBUG_DEBUG, "I am forwarding a local change to a global gline "
- "to a remote server; target %s, mask %s, operforce %s, action %s",
+ "to a remote server; target %s, mask %s, operforce %s, action %c",
target, mask, flags & GLINE_OPERFORCE ? "YES" : "NO",
- action == GLINE_LOCAL_ACTIVATE ? ">" : "<"));
+ action == GLINE_LOCAL_ACTIVATE ? '>' : '<'));
sendcmdto_one(sptr, CMD_GLINE, acptr, "%C %s%c%s", acptr,
flags & GLINE_OPERFORCE ? "!" : "",
- action == GLINE_LOCAL_ACTIVATE ? ">" : "<", mask);
+ action == GLINE_LOCAL_ACTIVATE ? '>' : '<', mask);
return 0; /* all done */
}
if (parc < 5) /* check parameter count... */
return need_more_params(sptr, "GLINE");
- expire_off = atoi(parv[3]); /* get expiration... */
+ expire = atoi(parv[3]); /* get expiration... */
+ expire = abs_expire(expire); /* convert to absolute... */
reason = parv[parc - 1]; /* and reason */
if (IsMe(acptr)) {
Debug((DEBUG_DEBUG, "I am creating a local G-line here; target %s, "
"mask %s, operforce %s, action %s, expire %Tu, reason: %s",
target, mask, flags & GLINE_OPERFORCE ? "YES" : "NO",
- action == GLINE_ACTIVATE ? "+" : "-", expire_off, reason));
+ action == GLINE_ACTIVATE ? "+" : "-", expire, reason));
- return gline_add(cptr, sptr, mask, reason, expire_off, lastmod,
+ return gline_add(cptr, sptr, mask, reason, expire, lastmod,
lifetime, flags | GLINE_ACTIVE);
}
} else if (IsMe(acptr)) { /* destroying a local G-line */
assert(!IsMe(acptr));
Debug((DEBUG_DEBUG, "I am forwarding a local G-line to a remote server; "
- "target %s, mask %s, operforce %s, action %s, expire %Tu, "
+ "target %s, mask %s, operforce %s, action %c, expire %Tu, "
"lastmod %Tu, reason: %s", target, mask,
flags & GLINE_OPERFORCE ? "YES" : "NO",
- action == GLINE_ACTIVATE ? "+" : "-", expire_off, CurrentTime,
+ action == GLINE_ACTIVATE ? '+' : '-', expire, CurrentTime,
reason));
sendcmdto_one(sptr, CMD_GLINE, acptr, "%C %s%c%s %Tu %Tu :%s",
acptr, flags & GLINE_OPERFORCE ? "!" : "",
- action == GLINE_ACTIVATE ? '+' : '-', mask, expire_off,
- CurrentTime, reason);
+ action == GLINE_ACTIVATE ? '+' : '-', mask,
+ expire - CurrentTime, CurrentTime, reason);
return 0; /* all done */
}
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 */
- if (parc < 5)
- return need_more_params(sptr, "GLINE");
-
- expire_off = atoi(parv[3]); /* convert expiration and lastmod */
+ 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 */
(action == GLINE_DEACTIVATE ? "-" :
(action == GLINE_LOCAL_ACTIVATE ? ">" :
(action == GLINE_LOCAL_DEACTIVATE ? "<" : "(MODIFY)"))),
- expire_off, lastmod, lifetime, reason,
+ expire, lastmod, lifetime, reason,
agline ? "EXISTS" : "does not exist",
flags & GLINE_EXPIRE ? "expire" : "",
flags & GLINE_LIFETIME ? "lifetime" : "",
* Let's actually do the action!
*/
if (agline)
- return gline_modify(cptr, sptr, agline, action, reason, expire_off,
+ 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);
- return gline_add(cptr, sptr, mask, reason, expire_off, lastmod, lifetime,
+ return gline_add(cptr, sptr, mask, reason, expire, lastmod, lifetime,
flags | ((action == GLINE_ACTIVATE) ? GLINE_ACTIVE : 0));
}
struct Gline *agline = 0;
unsigned int flags = 0;
enum GlineAction action = GLINE_MODIFY;
- time_t expire_off = 0;
+ time_t expire = 0;
char *mask = parv[1], *target = 0, *reason = 0;
if (parc < 2)
return need_more_params(sptr, "GLINE");
target = parv[2]; /* get the target... */
- expire_off = atoi(parv[3]); /* and the expiration */
+ expire = atoi(parv[3]) + CurrentTime; /* and the expiration */
flags |= GLINE_EXPIRE; /* remember that we got an expire time */
if (parc > 4) { /* also got a reason... */
- reason = parv[4];
+ reason = parv[parc - 1];
flags |= GLINE_REASON;
}
if (parc > 3) {
/* get expiration and target */
- expire_off = atoi(parv[parc - 2]);
+ expire = atoi(parv[parc - 2]) + CurrentTime;
reason = parv[parc - 1];
flags |= GLINE_EXPIRE | GLINE_REASON; /* remember that we got 'em */
return send_reply(sptr, ERR_NOPRIVILEGES);
Debug((DEBUG_DEBUG, "I am forwarding a local change to a global gline "
- "to a remote server; target %s, mask %s, operforce %s, action %s",
+ "to a remote server; target %s, mask %s, operforce %s, action %c",
cli_name(acptr), mask, flags & GLINE_OPERFORCE ? "YES" : "NO",
- action == GLINE_LOCAL_ACTIVATE ? ">" : "<"));
+ action == GLINE_LOCAL_ACTIVATE ? '>' : '<'));
sendcmdto_one(sptr, CMD_GLINE, acptr, "%C %s%c%s", acptr,
flags & GLINE_OPERFORCE ? "!" : "",
- action == GLINE_LOCAL_ACTIVATE ? ">" : "<", mask);
+ action == GLINE_LOCAL_ACTIVATE ? '>' : '<', mask);
return 0; /* all done */
}
return send_reply(sptr, ERR_NOPRIVILEGES);
Debug((DEBUG_DEBUG, "I am forwarding a local G-line to a remote "
- "server; target %s, mask %s, operforce %s, action %s, "
+ "server; target %s, mask %s, operforce %s, action %c, "
"expire %Tu, reason %s", target, mask,
flags & GLINE_OPERFORCE ? "YES" : "NO",
- action == GLINE_ACTIVATE ? "+" : "-", expire_off, reason));
+ action == GLINE_ACTIVATE ? '+' : '-', expire, reason));
sendcmdto_one(sptr, CMD_GLINE, acptr, "%C %s%c%s %Tu %Tu :%s",
acptr, flags & GLINE_OPERFORCE ? "!" : "",
- action == GLINE_ACTIVATE ? "+" : "-", mask, expire_off,
- CurrentTime, reason);
+ action == GLINE_ACTIVATE ? '+' : '-', mask,
+ expire - CurrentTime, CurrentTime, reason);
return 0; /* all done */
}
Debug((DEBUG_DEBUG, "I am creating a local G-line here; target %s, "
"mask %s, operforce %s, action %s, expire %Tu, reason: %s",
target, mask, flags & GLINE_OPERFORCE ? "YES" : "NO",
- action == GLINE_ACTIVATE ? "+" : "-", expire_off, reason));
+ action == GLINE_ACTIVATE ? "+" : "-", expire, reason));
- return gline_add(cptr, sptr, mask, reason, expire_off, 0, 0,
+ return gline_add(cptr, sptr, mask, reason, expire, 0, 0,
flags | GLINE_ACTIVE);
} else { /* OK, it's a deactivation/destruction */
if (!agline) /* G-line doesn't exist, so let's complain... */
(action == GLINE_DEACTIVATE ? "-" :
(action == GLINE_LOCAL_ACTIVATE ? ">" :
(action == GLINE_LOCAL_DEACTIVATE ? "<" : "(MODIFY)"))),
- expire_off, reason, agline ? "EXISTS" : "does not exist",
+ expire, reason, agline ? "EXISTS" : "does not exist",
flags & GLINE_EXPIRE ? "expire" : "",
flags & GLINE_REASON ? "reason" : ""));
if (agline) /* modifying an existing G-line */
- return gline_modify(cptr, sptr, agline, action, reason, expire_off,
+ return gline_modify(cptr, sptr, agline, action, reason, expire,
CurrentTime, 0, flags);
assert(action != GLINE_LOCAL_ACTIVATE);
assert(action != GLINE_MODIFY);
/* create a new G-line */
- return gline_add(cptr, sptr, mask, reason, expire_off, CurrentTime, 0,
+ return gline_add(cptr, sptr, mask, reason, expire, CurrentTime, 0,
flags | ((action == GLINE_ACTIVATE) ? GLINE_ACTIVE : 0));
}