--- /dev/null
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <string.h>
+#include "subscription.h"
+#include "stringbucket.h"
+#include "config.h"
+
+int subscription_add(const char *from, const char *to) {
+ char filename[512];
+ struct stringbucket * sb;
+
+ snprintf(filename, 512, "%s/%s/subscriptions", DATA_PATH, from);
+ sb = stringbucket_open(filename);
+ stringbucket_add(sb, to);
+ stringbucket_close(sb);
+
+ snprintf(filename, 512, "%s/%s/subscribers", DATA_PATH, to);
+ sb = stringbucket_open(filename);
+ stringbucket_add(sb, from);
+ stringbucket_close(sb);
+}
+
+int subscription_remove(const char *from, const char *to) {
+ char filename[512];
+ struct stringbucket * sb;
+
+ snprintf(filename, 512, "%s/%s/subscriptions", DATA_PATH, from);
+ sb = stringbucket_open(filename);
+ stringbucket_delete(sb, to);
+ stringbucket_close(sb);
+
+ snprintf(filename, 512, "%s/%s/subscribers", DATA_PATH, to);
+ sb = stringbucket_open(filename);
+ stringbucket_delete(sb, from);
+ stringbucket_close(sb);
+}
+
+void subscription_notify_add_item(char *to, void *stuff) {
+ char filename[512];
+
+ snprintf(filename, 512, "%s/%s/subscription_feed", DATA_PATH, to);
+ int fd = open(filename, O_WRONLY | O_APPEND | O_CREAT);
+ write(fd, stuff, sizeof(struct subscription_record));
+ close(fd);
+}
+
+int subscription_notify(const char *author, uint64_t record) {
+ char filename[512];
+ struct subscription_record r;
+
+ strncpy(r.author, author, 32);
+ r.record = record;
+
+ snprintf(filename, 512, "%s/%s/subscribers", DATA_PATH, author);
+ struct stringbucket * sb = stringbucket_open(filename);
+ stringbucket_iterate(sb, subscription_notify_add_item, &r);
+ stringbucket_close(sb);
+}