+
+
+/*
+ * compact (defragment) the database , possibly returning space back to the underlying filesystem
+ */
+void cdb_compact(void)
+{
+ int ret;
+ int i;
+
+ syslog(LOG_DEBUG, "db: cdb_compact() started");
+ for (i = 0; i < MAXCDB; i++) {
+ syslog(LOG_DEBUG, "db: compacting database %d", i);
+ ret = dbp[i]->compact(dbp[i], NULL, NULL, NULL, NULL, DB_FREE_SPACE, NULL);
+ if (ret) {
+ syslog(LOG_ERR, "db: compact: %s", db_strerror(ret));
+ }
+ }
+ syslog(LOG_DEBUG, "db: cdb_compact() finished");
+}
+
+
+// Has an item already been seen (is it in the CDB_USETABLE) ?
+// Returns 0 if it hasn't, 1 if it has
+// In either case, writes the item to the database for next time.
+int CheckIfAlreadySeen(StrBuf *guid)
+{
+ int found = 0;
+ struct UseTable ut;
+ struct cdbdata *cdbut;
+
+ syslog(LOG_DEBUG, "db: CheckIfAlreadySeen(%s)", ChrPtr(guid));
+ cdbut = cdb_fetch(CDB_USETABLE, SKEY(guid));
+ if (cdbut != NULL) {
+ found = 1;
+ cdb_free(cdbut);
+ }
+
+ /* (Re)write the record, to update the timestamp. Zeroing it out makes it compress better. */
+ memset(&ut, 0, sizeof(struct UseTable));
+ memcpy(ut.ut_msgid, SKEY(guid));
+ ut.ut_timestamp = time(NULL);
+ cdb_store(CDB_USETABLE, SKEY(guid), &ut, sizeof(struct UseTable));
+ return (found);
+}
+
+
+void cmd_rsen(char *argbuf)
+{
+ char Token[SIZ];
+ long TLen;
+ char Time[SIZ];
+
+ struct UseTable ut;
+ struct cdbdata *cdbut;
+
+ if (CtdlAccessCheck(ac_aide)) {
+ return;
+ }
+
+ TLen = extract_token(Token, argbuf, 1, '|', sizeof Token);
+ if (strncmp(argbuf, "GET", 3) == 0) {
+ cdbut = cdb_fetch(CDB_USETABLE, Token, TLen);
+ if (cdbut != NULL) {
+ memcpy(&ut, cdbut->ptr, ((cdbut->len > sizeof(struct UseTable)) ? sizeof(struct UseTable) : cdbut->len));
+
+ cprintf("%d %ld\n", CIT_OK, ut.ut_timestamp);
+ } else {
+ cprintf("%d not found\n", ERROR + NOT_HERE);
+ }
+
+ } else if (strncmp(argbuf, "SET", 3) == 0) {
+ memcpy(ut.ut_msgid, Token, TLen);
+ extract_token(Time, argbuf, 2, '|', sizeof Time);
+ ut.ut_timestamp = atol(Time);
+ cdb_store(CDB_USETABLE, Token, TLen, &ut, sizeof(struct UseTable));
+ cprintf("%d token updated\n", CIT_OK);
+ } else if (strncmp(argbuf, "DEL", 3) == 0) {
+ if (cdb_delete(CDB_USETABLE, Token, TLen))
+ cprintf("%d not found\n", ERROR + NOT_HERE);
+ else
+ cprintf("%d deleted.\n", CIT_OK);
+
+ } else {
+ cprintf("%d Usage: [GET|SET|DEL]|Token|timestamp\n", ERROR);
+ }
+
+}
+
+
+CTDL_MODULE_INIT(database)
+{
+ if (!threading) {
+ CtdlRegisterProtoHook(cmd_rsen, "RSEN", "manipulate Aggregators seen database");
+ }
+
+ /* return our module id for the log */
+ return "database";
+}