X-Git-Url: http://git.bytex64.net/?a=blobdiff_plain;f=database%2Fsubscription.c;fp=database%2Fsubscription.c;h=d67d31f51ef6b2d30733e08e7e460e859c5b4473;hb=ec8746b44dc85fd3e3b42835f779890684a9e90a;hp=e6ae94a101e89f0a5104d48a74581b03f9c93f61;hpb=dead5bdc521b34c85256737b616f4072a78dc2fb;p=blerg.git diff --git a/database/subscription.c b/database/subscription.c index e6ae94a..d67d31f 100644 --- a/database/subscription.c +++ b/database/subscription.c @@ -1,7 +1,12 @@ +/* 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 "subscription.h" #include "stringbucket.h" @@ -41,14 +46,14 @@ 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)); + 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; + struct blergref r; strncpy(r.author, author, 32); r.record = record; @@ -58,3 +63,68 @@ int subscription_notify(const char *author, uint64_t record) { stringbucket_iterate(sb, subscription_notify_add_item, &r); stringbucket_close(sb); } + +struct blergref * subscription_list(const char *author, uint64_t offset, int *count, int direction) { + char filename[512]; + struct stat st; + struct blergref * slist; + struct blergref * retlist; + uint64_t n_subscription_records; + + if (!valid_name(author)) + return NULL; + + snprintf(filename, 512, "%s/%s/subscription_feed", DATA_PATH, author); + + int feed_fd = open(filename, O_RDONLY); + if (feed_fd == -1) { + perror("Could not open subscription feed"); + goto subscription_list_map_failed; + } + + fstat(feed_fd, &st); + if (st.st_size == 0) { + close(feed_fd); + 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; +}