+
+int glinebufwritelog(glinebuf *gbuf, int propagating) {
+ int i, slot;
+ gline *gl, *sgl;
+ glinebuf *gbl;
+
+ if (!gbuf->glines)
+ return 0; /* Don't waste log IDs on empty gline buffers */
+
+ gbl = NULL;
+
+ /* Find an existing log buffer with the same id */
+ if (gbuf->id != 0) {
+ for (i = 0; i < MAXGLINELOG; i++) {
+ if (!glinebuflog[i])
+ continue;
+
+ if (glinebuflog[i]->id == gbuf->id) {
+ gbl = glinebuflog[i];
+ gbl->amend = gbuf->commit;
+
+ /* We're going to re-insert this glinebuf, so remove it for now */
+ glinebuflog[i] = NULL;
+
+ break;
+ }
+ }
+ }
+
+ /* Find a recent glinebuf that's a close match */
+ if (!gbl && !propagating) {
+ for (i = 0; i < MAXGLINELOG; i++) {
+ if (!glinebuflog[i])
+ continue;
+
+ if (glinebuflog[i]->commit < getnettime() - 5 && glinebuflog[i]->amend < getnettime() - 5)
+ continue;
+
+ assert(glinebuflog[i]->glines);
+
+ if (strcmp(glinebuflog[i]->glines->creator->content, gbuf->glines->creator->content) != 0)
+ continue;
+
+ gbl = glinebuflog[i];
+ gbl->amend = gbuf->commit;
+
+ /* We're going to re-insert this glinebuf, so remove it for now */
+ glinebuflog[i] = NULL;
+
+ break;
+ }
+ }
+
+ /* Make a new glinebuf for the log */
+ if (!gbl) {
+ gbl = malloc(sizeof(glinebuf));
+ glinebufinit(gbl, (gbuf->id == 0) ? nextglinebufid++ : gbuf->id);
+
+ assert(gbl->hitsvalid);
+
+ if (gbuf->comment)
+ glinebufcommentf(gbl, "%s", gbuf->comment->content);
+ else if (!propagating)
+ glinebufcommentf(gbl, "G-Lines set by %s", gbuf->glines->creator->content);
+
+ gbl->commit = gbuf->commit;
+ }
+
+ /* Save a duplicate of the glines in the log buffer */
+ for (gl = gbuf->glines; gl; gl = gl->next) {
+ sgl = glinedup(gl);
+ sgl->next = gbl->glines;
+ gbl->glines = sgl;
+ }
+
+ gbl->userhits += gbuf->userhits;
+ gbl->channelhits += gbuf->channelhits;
+
+ assert(gbuf->userhits + gbuf->channelhits == gbuf->hits.cursi);
+
+ for (i = 0; i < gbuf->hits.cursi; i++) {
+ slot = array_getfreeslot(&gbl->hits);
+ ((sstring **)gbl->hits.content)[slot] = getsstring(((sstring **)gbuf->hits.content)[i]->content, 512);
+ }
+
+ /* Log the transaction */
+ glinebuflogoffset++;
+
+ if (glinebuflogoffset >= MAXGLINELOG)
+ glinebuflogoffset = 0;
+
+ if (glinebuflog[glinebuflogoffset])
+ glinebufabort(glinebuflog[glinebuflogoffset]);
+
+ glinebuflog[glinebuflogoffset] = gbl;
+
+ return gbl->id;
+}