+static int glines_cmdglinelog(void *source, int cargc, char **cargv) {
+ nick *sender = source;
+ glinebuf *gbl;
+ gline *gl;
+ int i, id, count;
+ char timebuf[30];
+
+ id = 0;
+
+ if (cargc > 0) {
+ id = atoi(cargv[0]);
+
+ if (id == 0) {
+ controlreply(sender, "Invalid log ID.");
+ return CMD_ERROR;
+ }
+ }
+
+ controlreply(sender, "Time ID G-Lines User Hits Channel Hits Comment");
+
+ for (i = 0; i < MAXGLINELOG; i++) {
+ gbl = glinebuflog[(i + glinebuflogoffset + 1) % MAXGLINELOG];
+
+ if (!gbl)
+ continue;
+
+ if (id == 0 || gbl->id == id) {
+ count = 0;
+
+ for (gl = gbl->glines; gl; gl = gl->next)
+ count++;
+
+ strftime(timebuf, sizeof(timebuf), "%d/%m/%y %H:%M:%S", localtime((gbl->amend) ? &gbl->amend : &gbl->commit));
+ strncat(timebuf, (gbl->amend) ? "*" : " ", sizeof(timebuf));
+ controlreply(sender, "%-20s %-10d %-10d %-15d %-15d %s", timebuf, gbl->id, count, gbl->userhits, gbl->channelhits, gbl->comment ? gbl->comment->content : "(no comment)");
+ }
+
+ if (id != 0 && gbl->id == id) {
+ glinebufspew(gbl, sender);
+ controlreply(sender, "Done.");
+ return CMD_OK;
+ }
+ }
+
+ if (id == 0) {
+ controlreply(sender, "Done.");
+ } else {
+ controlreply(sender, "Log entry for ID %d not found.", id);
+ }
+
+ return CMD_OK;
+}
+
+static int glines_cmdglineundo(void *source, int cargc, char **cargv) {
+ nick *sender = source;
+ int id;
+
+ if (cargc < 1)
+ return CMD_USAGE;
+
+ id = atoi(cargv[0]);
+
+ if (id == 0 || !glinebufundo(id)) {
+ controlreply(sender, "Invalid log ID.");
+ return CMD_ERROR;
+ }
+
+ controlreply(sender, "Done.");
+
+ return CMD_OK;
+}
+
+static int glines_cmdsyncglines(void *source, int cargc, char **cargv) {
+ nick *sender = source;
+ gline *gl;
+ int count;
+
+ count = 0;
+
+ for (gl = glinelist; gl; gl = gl->next) {
+ gline_propagate(gl);
+ count++;
+ }
+
+ controlwall(NO_OPER, NL_GLINES, "%s SYNCGLINE'd %d G-Lines.",
+ controlid(sender), count);
+
+ controlreply(sender, "Done.");
+
+ return CMD_OK;
+}
+
+static int glines_cmdcleanupglines(void *source, int cargc, char **cargv) {
+ nick *sender = source;
+ gline **pnext, *gl;
+ int count;
+ time_t now;
+
+ count = 0;
+ time(&now);
+
+ for (pnext = &glinelist; *pnext;) {
+ gl = *pnext;
+
+ /* Remove inactivate glines that have been last changed more than a week ago */
+ if (!(gl->flags & GLINE_ACTIVE) && gl->lastmod < now - 7 * 24 * 60 * 60) {
+ gline_destroy(gl, 0, 1);
+ count++;
+ } else {
+ pnext = &((*pnext)->next);
+ }
+
+ if (!*pnext)
+ break;
+ }
+
+ controlwall(NO_OPER, NL_GLINES, "%s CLEANUPGLINES'd %d G-Lines.",
+ controlid(sender), count);
+
+ controlreply(sender, "Done.");
+
+ return CMD_OK;
+}
+