X-Git-Url: http://git.bytex64.net/?a=blobdiff_plain;f=database%2Fsubscription.c;h=c1633fea1c994cc297e2a782e6a84452aee89e82;hb=948ce5be6ef6bba36edfb544565ca22e316afb0a;hp=e6ae94a101e89f0a5104d48a74581b03f9c93f61;hpb=bfc01c15f56c58cefc8680f7faed4c5e3650fa38;p=blerg.git diff --git a/database/subscription.c b/database/subscription.c index e6ae94a..c1633fe 100644 --- a/database/subscription.c +++ b/database/subscription.c @@ -1,60 +1,168 @@ +/* Blerg is (C) 2011 The Dominion of Awesome, and is distributed under a + * BSD-style license. Please see the COPYING file for details. + */ #include #include -#include +#include +#include +#include #include +#include #include #include "subscription.h" #include "stringbucket.h" +#include "util.h" #include "config.h" +#include "configuration.h" int subscription_add(const char *from, const char *to) { - char filename[512]; + char filename[FILENAME_MAX]; struct stringbucket * sb; - snprintf(filename, 512, "%s/%s/subscriptions", DATA_PATH, from); + snprintf(filename, FILENAME_MAX, "%s/%s/subscriptions", blergconf.data_path, from); sb = stringbucket_open(filename); stringbucket_add(sb, to); stringbucket_close(sb); - snprintf(filename, 512, "%s/%s/subscribers", DATA_PATH, to); + snprintf(filename, FILENAME_MAX, "%s/%s/subscribers", blergconf.data_path, to); sb = stringbucket_open(filename); stringbucket_add(sb, from); stringbucket_close(sb); + + return 1; } int subscription_remove(const char *from, const char *to) { - char filename[512]; + char filename[FILENAME_MAX]; struct stringbucket * sb; - snprintf(filename, 512, "%s/%s/subscriptions", DATA_PATH, from); + snprintf(filename, FILENAME_MAX, "%s/%s/subscriptions", blergconf.data_path, from); sb = stringbucket_open(filename); stringbucket_delete(sb, to); stringbucket_close(sb); - snprintf(filename, 512, "%s/%s/subscribers", DATA_PATH, to); + snprintf(filename, FILENAME_MAX, "%s/%s/subscribers", blergconf.data_path, to); sb = stringbucket_open(filename); stringbucket_delete(sb, from); stringbucket_close(sb); + + return 1; } void subscription_notify_add_item(char *to, void *stuff) { - char filename[512]; + char filename[FILENAME_MAX]; - 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)); + snprintf(filename, FILENAME_MAX, "%s/%s/subscription_feed", blergconf.data_path, to); + int fd = open(filename, O_WRONLY | O_APPEND | O_CREAT, 0600); + write(fd, stuff, sizeof(struct blergref)); close(fd); } int subscription_notify(const char *author, uint64_t record) { - char filename[512]; - struct subscription_record r; + char filename[FILENAME_MAX]; + struct blergref r; strncpy(r.author, author, 32); r.record = record; - snprintf(filename, 512, "%s/%s/subscribers", DATA_PATH, author); + snprintf(filename, FILENAME_MAX, "%s/%s/subscribers", blergconf.data_path, author); struct stringbucket * sb = stringbucket_open(filename); stringbucket_iterate(sb, subscription_notify_add_item, &r); stringbucket_close(sb); + + return 1; +} + +struct blergref * subscription_list(const char *author, uint64_t offset, int *count, int direction) { + char filename[FILENAME_MAX]; + struct stat st; + struct blergref * slist; + struct blergref * retlist; + uint64_t n_subscription_records; + + if (!valid_name(author)) + return NULL; + + snprintf(filename, FILENAME_MAX, "%s/%s/subscription_feed", blergconf.data_path, author); + + int feed_fd = open(filename, O_RDONLY); + if (feed_fd == -1) { + perror("Could not open subscription feed"); + goto subscription_list_open_failed; + } + + fstat(feed_fd, &st); + if (st.st_size == 0) { + fprintf(stderr, "Feed is empty\n"); + goto subscription_list_map_failed; + } + n_subscription_records = st.st_size / sizeof(struct blergref); + if (*count > n_subscription_records - offset) + *count = n_subscription_records - offset; + if (offset > n_subscription_records) { + fprintf(stderr, "Cannot access subscription record beyond end\n"); + goto subscription_list_map_failed; + close(feed_fd); + return NULL; + } + + slist = (struct blergref *) mmap(NULL, st.st_size, PROT_READ, MAP_SHARED, feed_fd, 0); + if (slist == MAP_FAILED) { + perror("Could not mmap tag_file"); + goto subscription_list_map_failed; + } + retlist = (struct blergref *) malloc(sizeof(struct blergref) * *count); + if (retlist == NULL) { + perror("Could not allocate memory for subscription feed list"); + goto subscription_list_malloc_failed; + } + + switch(direction) { + case 1: + memcpy(retlist, slist + offset, sizeof(struct blergref) * *count); + break; + case -1: + memcpy(retlist, slist + (n_subscription_records - *count - offset), sizeof(struct blergref) * *count); + } + + munmap(slist, st.st_size); + close(feed_fd); + return retlist; + +subscription_list_malloc_failed: + munmap(slist, st.st_size); +subscription_list_map_failed: + close(feed_fd); +subscription_list_open_failed: + *count = 0; + return NULL; +} + +int is_subscribed(const char *from, const char *to) { + char filename[FILENAME_MAX]; + struct stringbucket * sb; + int ret = 0; + + snprintf(filename, FILENAME_MAX, "%s/%s/subscriptions", blergconf.data_path, from); + sb = stringbucket_open(filename); + if (stringbucket_find(sb, to) != -1) + ret = 1; + stringbucket_close(sb); + + return ret; +} + +int subscription_count_items(const char *user) { + char filename[FILENAME_MAX]; + struct stat st; + + if (!valid_name(user)) + return -1; + + snprintf(filename, FILENAME_MAX, "%s/%s/subscription_feed", blergconf.data_path, user); + + if (access(filename, R_OK) != 0) + return 0; + stat(filename, &st); + return st.st_size / sizeof(struct blergref); }