chiark / gitweb /
Build fix for Linux
[disorder] / lib / trackdb.c
index 8e775d5626bc15033c2bf554a784d6c51dc97c24..4009358573a01a68e97ab868102b40e93b2b6908 100644 (file)
  * This file is getting in desparate need of splitting up...
  */
 
-#include <config.h>
-#include "types.h"
+#include "common.h"
 
-#include <string.h>
-#include <stdio.h>
 #include <db.h>
 #include <sys/socket.h>
 #include <pcre.h>
-#include <assert.h>
 #include <unistd.h>
 #include <errno.h>
 #include <stddef.h>
@@ -39,7 +35,6 @@
 #include <sys/resource.h>
 #include <time.h>
 #include <arpa/inet.h>
-#include <sys/wait.h>
 #include <dirent.h>
 #include <sys/stat.h>
 #include <gcrypt.h>
@@ -145,6 +140,17 @@ DB *trackdb_globaldb;                   /* global preferences */
  */
 DB *trackdb_noticeddb;                   /* when track noticed */
 
+/** @brief The schedule database
+ *
+ * - Keys are ID strings, generated at random
+ * - Values are encoded key-value pairs
+ * - There can be more than one value per key
+ * - Data cannot be reconstructed
+ *
+ * See @ref server/schedule.c for further information.
+ */
+DB *trackdb_scheduledb;
+
 /** @brief The user database
  * - Keys are usernames
  * - Values are encoded key-value pairs
@@ -460,6 +466,7 @@ void trackdb_open(int flags) {
   trackdb_globaldb = open_db("global.db", 0, DB_HASH, dbflags, 0666);
   trackdb_noticeddb = open_db("noticed.db",
                              DB_DUPSORT, DB_BTREE, dbflags, 0666);
+  trackdb_scheduledb = open_db("schedule.db", 0, DB_HASH, dbflags, 0666);
   if(!trackdb_existing_database) {
     /* Stash the database version */
     char buf[32];
@@ -490,6 +497,8 @@ void trackdb_close(void) {
     fatal(0, "error closing global.db: %s", db_strerror(err));
   if((err = trackdb_noticeddb->close(trackdb_noticeddb, 0)))
     fatal(0, "error closing noticed.db: %s", db_strerror(err));
+  if((err = trackdb_scheduledb->close(trackdb_scheduledb, 0)))
+    fatal(0, "error closing schedule.db: %s", db_strerror(err));
   if((err = trackdb_usersdb->close(trackdb_usersdb, 0)))
     fatal(0, "error closing users.db: %s", db_strerror(err));
   trackdb_tracksdb = trackdb_searchdb = trackdb_prefsdb = 0;
@@ -2157,6 +2166,28 @@ int trackdb_scan(const char *root,
 
 /* trackdb_rescan ************************************************************/
 
+/** @brief Node in the list of rescan-complete callbacks */
+struct rescanned_node {
+  struct rescanned_node *next;
+  void (*rescanned)(void *ru);
+  void *ru;
+};
+
+/** @brief List of rescan-complete callbacks */
+static struct rescanned_node *rescanned_list;
+
+/** @brief Add a rescan completion callback */
+void trackdb_add_rescanned(void (*rescanned)(void *ru),
+                           void *ru) {
+  if(rescanned) {
+    struct rescanned_node *n = xmalloc(sizeof *n);
+    n->next = rescanned_list;
+    n->rescanned = rescanned;
+    n->ru = ru;
+    rescanned_list = n;
+  }
+}
+
 /* called when the rescanner terminates */
 static int reap_rescan(ev_source attribute((unused)) *ev,
                        pid_t pid,
@@ -2171,23 +2202,37 @@ static int reap_rescan(ev_source attribute((unused)) *ev,
   /* Our cache of file lookups is out of date now */
   cache_clean(&cache_files_type);
   eventlog("rescanned", (char *)0);
+  /* Call rescanned callbacks */
+  while(rescanned_list) {
+    void (*rescanned)(void *u_) = rescanned_list->rescanned;
+    void *ru = rescanned_list->ru;
+
+    rescanned_list = rescanned_list->next;
+    rescanned(ru);
+  }
   return 0;
 }
 
 /** @brief Initiate a rescan
  * @param ev Event loop or 0 to block
  * @param recheck 1 to recheck lengths, 0 to suppress check
+ * @param rescanned Called on completion (if not NULL)
+ * @param u Passed to @p rescanned
  */
-void trackdb_rescan(ev_source *ev, int recheck) {
+void trackdb_rescan(ev_source *ev, int recheck,
+                    void (*rescanned)(void *ru),
+                    void *ru) {
   int w;
 
   if(rescan_pid != -1) {
+    trackdb_add_rescanned(rescanned, ru);
     error(0, "rescan already underway");
     return;
   }
   rescan_pid = subprogram(ev, -1, RESCAN,
                           recheck ? "--check" : "--no-check",
                           (char *)0);
+  trackdb_add_rescanned(rescanned, ru);
   if(ev) {
     ev_child(ev, rescan_pid, 0, reap_rescan, 0);
     D(("started rescanner"));
@@ -2207,6 +2252,11 @@ int trackdb_rescan_cancel(void) {
   return 1;
 }
 
+/** @brief Return true if a rescan is underway */
+int trackdb_rescan_underway(void) {
+  return rescan_pid != -1;
+}
+
 /* global prefs **************************************************************/
 
 void trackdb_set_global(const char *name,