00001 #include <microfeed-common/microfeedconfiguration.h>
00002 #include <microfeed-common/microfeedmisc.h>
00003 #include <microfeed-common/microfeedstore.h>
00004
00005 #include <stdlib.h>
00006 #include <string.h>
00007 #include <sys/types.h>
00008 #include <sys/stat.h>
00009 #include <fcntl.h>
00010 #include <unistd.h>
00011 #include <libgen.h>
00012
00013 struct _MicrofeedConfiguration {
00014 char* providers_environment_directory;
00015 char* providers_home_directory;
00016 char* publishers_environment_directory;
00017 char* publishers_home_directory;
00018 char* subscribers_environment_directory;
00019 char* subscribers_home_directory;
00020 char* wizards_environment_directory;
00021 char* wizards_home_directory;
00022 const char** providers;
00023 const char** provider_directories;
00024 const char** provider_names;
00025 const char*** provider_feeds;
00026 const char** publishers;
00027 const char** publisher_directories;
00028 MicrofeedStore* subscriptions;
00029 const char** wizards;
00030 const char** wizard_directories;
00031 const char** wizard_names;
00032 const char*** wizard_settings;
00033 };
00034
00035 typedef struct {
00036 char* application_identifier;
00037 char* filename;
00038 const char** subscriptions;
00039 } Subscription;
00040
00041 static Subscription* subscription_new(const char* application_identifier, const char* filename, const char** subscriptions);
00042 static void subscription_free(Subscription* subscription);
00043 static const char* subscription_get_application_identifier(Subscription* subscription);
00044 static void subscription_save(Subscription* subscription);
00045
00046 static ssize_t read_line(int fd, size_t offset, char* buffer, size_t buffer_size);
00047 static void get_providers(MicrofeedConfiguration* configuration, const char* directory, unsigned int* length_pointer);
00048 static void get_publishers(MicrofeedConfiguration* configuration, const char* directory, unsigned int* length_pointer);
00049 static void get_wizards(MicrofeedConfiguration* configuration, const char* directory, unsigned int* length_pointer);
00050 static void update_providers(MicrofeedConfiguration* configuration);
00051 static void update_publishers(MicrofeedConfiguration* configuration);
00052 static void update_wizards(MicrofeedConfiguration* configuration);
00053 static int update_and_get_provider_index(MicrofeedConfiguration* configuration, const char* provider_identifier);
00054 static int update_and_get_wizard_index(MicrofeedConfiguration* configuration, const char* provider_identifier);
00055 static Subscription* update_and_get_subscription(MicrofeedConfiguration* configuration, const char* application_identifier);
00056
00057 MicrofeedConfiguration* microfeed_configuration_new(void) {
00058 MicrofeedConfiguration* configuration;
00059 char* directory;
00060 size_t length;
00061
00062 configuration = microfeed_memory_allocate(MicrofeedConfiguration);
00063 if ((directory = getenv("MICROFEED_PROVIDERS_DIRECTORY"))) {
00064 configuration->providers_environment_directory = strdup(directory);
00065 }
00066 if ((directory = getenv("MICROFEED_PUBLISHERS_DIRECTORY"))) {
00067 configuration->publishers_environment_directory = strdup(directory);
00068 }
00069 if ((directory = getenv("MICROFEED_SUBSCRIBERS_DIRECTORY"))) {
00070 configuration->subscribers_environment_directory = strdup(directory);
00071 }
00072 if ((directory = getenv("MICROFEED_WIZARDS_DIRECTORY"))) {
00073 configuration->wizards_environment_directory = strdup(directory);
00074 }
00075 if ((directory = getenv("HOME"))) {
00076 length = strlen(directory);
00077 configuration->providers_home_directory = microfeed_memory_allocate_bytes(length + 22);
00078 memcpy(configuration->providers_home_directory, directory, length);
00079 memcpy(configuration->providers_home_directory + length, "/.microfeed/providers", 22);
00080 configuration->publishers_home_directory = microfeed_memory_allocate_bytes(length + 23);
00081 memcpy(configuration->publishers_home_directory, directory, length);
00082 memcpy(configuration->publishers_home_directory + length, "/.microfeed/publishers", 23);
00083 configuration->subscribers_home_directory = microfeed_memory_allocate_bytes(length + 24);
00084 memcpy(configuration->subscribers_home_directory, directory, length);
00085 memcpy(configuration->subscribers_home_directory + length, "/.microfeed/subscribers", 24);
00086 configuration->wizards_home_directory = microfeed_memory_allocate_bytes(length + 20);
00087 memcpy(configuration->wizards_home_directory, directory, length);
00088 memcpy(configuration->wizards_home_directory + length, "/.microfeed/wizards", 20);
00089 }
00090 configuration->subscriptions = microfeed_store_new_sorted((MicrofeedStoreCompareKeysFunction)strcmp, (MicrofeedStoreGetKeyFunction)subscription_get_application_identifier);
00091
00092 return configuration;
00093 }
00094
00095 void microfeed_configuration_free(MicrofeedConfiguration* configuration) {
00096 microfeed_configuration_invalidate(configuration);
00097 free(configuration->providers_environment_directory);
00098 free(configuration->publishers_environment_directory);
00099 free(configuration->subscribers_environment_directory);
00100 free(configuration->wizards_environment_directory);
00101 microfeed_memory_free(configuration->providers_home_directory);
00102 microfeed_memory_free(configuration->publishers_home_directory);
00103 microfeed_memory_free(configuration->subscribers_home_directory);
00104 microfeed_store_free(configuration->subscriptions);
00105 microfeed_memory_free(configuration->wizards_home_directory);
00106
00107 microfeed_memory_free(configuration);
00108 }
00109
00110 void microfeed_configuration_invalidate(MicrofeedConfiguration* configuration) {
00111 int i;
00112 int k;
00113
00114 if (configuration->providers) {
00115 for (i = 0; configuration->providers[i]; i++) {
00116 free((void*)configuration->providers[i]);
00117
00118 free((void*)configuration->provider_names[i]);
00119 if (configuration->provider_feeds[i]) {
00120 for (k = 0; configuration->provider_feeds[i][k]; k++) {
00121 free((void*)configuration->provider_feeds[i][k]);
00122 }
00123 free(configuration->provider_feeds[i]);
00124 }
00125 }
00126 free(configuration->providers);
00127 free(configuration->provider_names);
00128 free(configuration->provider_feeds);
00129 free(configuration->provider_directories);
00130 configuration->providers = NULL;
00131 configuration->provider_names = NULL;
00132 configuration->provider_feeds = NULL;
00133 configuration->provider_directories = NULL;
00134 }
00135
00136 if (configuration->publishers) {
00137 for (i = 0; configuration->publishers[i]; i++) {
00138 free((void*)configuration->publishers[i]);
00139
00140 }
00141 free(configuration->publishers);
00142 free(configuration->publisher_directories);
00143 configuration->publishers = NULL;
00144 configuration->publisher_directories = NULL;
00145 }
00146 microfeed_store_remove_and_free_all(configuration->subscriptions, (MicrofeedStoreFreeDataFunction)subscription_free);
00147 if (configuration->wizards) {
00148 for (i = 0; configuration->wizards[i]; i++) {
00149 free((void*)configuration->wizards[i]);
00150
00151 free((void*)configuration->wizard_names[i]);
00152 if (configuration->wizard_settings[i]) {
00153 for (k = 0; configuration->wizard_settings[i][k]; k++) {
00154 free((void*)configuration->wizard_settings[i][k]);
00155 }
00156 free(configuration->wizard_settings[i]);
00157 }
00158 }
00159 free(configuration->wizards);
00160 free(configuration->wizard_names);
00161 free(configuration->wizard_settings);
00162 free(configuration->wizard_directories);
00163 configuration->wizards = NULL;
00164 configuration->wizard_names = NULL;
00165 configuration->wizard_settings = NULL;
00166 configuration->wizard_directories = NULL;
00167 }
00168 }
00169
00170 const char** microfeed_configuration_get_providers(MicrofeedConfiguration* configuration) {
00171 if (!configuration->providers) {
00172 update_providers(configuration);
00173 }
00174
00175 return configuration->providers;
00176 }
00177
00178 const char* microfeed_configuration_get_provider_name(MicrofeedConfiguration* configuration, const char* provider_identifier) {
00179 const char* name = NULL;
00180 int index;
00181
00182 if ((index = update_and_get_provider_index(configuration, provider_identifier)) != -1) {
00183 name = configuration->provider_names[index];
00184 }
00185
00186 return name;
00187 }
00188
00189 const char* microfeed_configuration_get_provider_directory(MicrofeedConfiguration* configuration, const char* provider_identifier) {
00190 const char* directory = NULL;
00191 unsigned int index;
00192 int difference = 1;
00193
00194 if (!configuration->providers) {
00195 update_providers(configuration);
00196 }
00197 if (configuration->providers) {
00198 for (index = 0; configuration->providers[index] && (difference = strcmp(configuration->providers[index], provider_identifier)) < 0; index++) {
00199 }
00200 if (!difference) {
00201 directory = configuration->provider_directories[index];
00202 }
00203 }
00204
00205 return directory;
00206 }
00207
00208 const char** microfeed_configuration_get_publishers(MicrofeedConfiguration* configuration) {
00209 if (!configuration->publishers) {
00210 update_publishers(configuration);
00211 }
00212
00213 return configuration->publishers;
00214 }
00215
00216 const char* microfeed_configuration_get_publisher_directory(MicrofeedConfiguration* configuration, const char* publisher_identifier) {
00217 const char* directory = NULL;
00218 unsigned int index;
00219 int difference = 1;
00220
00221 if (!configuration->publishers) {
00222 update_publishers(configuration);
00223 }
00224 if (configuration->publishers) {
00225 for (index = 0, difference = 1; configuration->publishers[index] && (difference = strcmp(configuration->publishers[index], publisher_identifier)) < 0; index++) {
00226 }
00227 if (!difference) {
00228 directory = configuration->publisher_directories[index];
00229 }
00230 }
00231
00232 return directory;
00233 }
00234
00235 const char* microfeed_configuration_get_default_publisher_directory(MicrofeedConfiguration* configuration) {
00236
00237 return (configuration->publishers_environment_directory ? configuration->publishers_environment_directory : configuration->publishers_home_directory);
00238 }
00239
00240 const char** microfeed_configuration_get_providers_predefined_feed_uris(MicrofeedConfiguration* configuration, const char* provider_identifier) {
00241 const char** feeds = NULL;
00242 int index;
00243
00244 if ((index = update_and_get_provider_index(configuration, provider_identifier)) != -1) {
00245 feeds = configuration->provider_feeds[index];
00246 }
00247
00248 return feeds;
00249 }
00250
00251 const char** microfeed_configuration_get_subscriptions(MicrofeedConfiguration* configuration, const char* application_identifier) {
00252 Subscription* subscription;
00253
00254 if (!(subscription = microfeed_store_get(configuration->subscriptions, application_identifier, Subscription))) {
00255 subscription = update_and_get_subscription(configuration, application_identifier);
00256 }
00257
00258 return (subscription ? subscription->subscriptions : NULL);
00259 }
00260
00261 void microfeed_configuration_add_subscription(MicrofeedConfiguration* configuration, const char* application_identifier, const char* publisher_identifier) {
00262 Subscription* subscription;
00263 int found;
00264 int i;
00265
00266 if (!(subscription = microfeed_store_get(configuration->subscriptions, application_identifier, Subscription))) {
00267 subscription = update_and_get_subscription(configuration, application_identifier);
00268 }
00269 if (subscription) {
00270 found = 0;
00271 for (i = 0; subscription->subscriptions[i]; i++) {
00272 if (!strcmp(subscription->subscriptions[i], publisher_identifier)) {
00273 found = 1;
00274 }
00275 }
00276 if (!found) {
00277 subscription->subscriptions = (const char**)realloc(subscription->subscriptions, (i + 2) * sizeof(char*));
00278 subscription->subscriptions[i] = strdup(publisher_identifier);
00279 subscription->subscriptions[i + 1] = NULL;
00280
00281 subscription_save(subscription);
00282 }
00283 }
00284 }
00285
00286 void microfeed_configuration_remove_subscription(MicrofeedConfiguration* configuration, const char* application_identifier, const char* publisher_identifier) {
00287 Subscription* subscription;
00288 int i;
00289 int index;
00290
00291 if (!(subscription = microfeed_store_get(configuration->subscriptions, application_identifier, Subscription))) {
00292 subscription = update_and_get_subscription(configuration, application_identifier);
00293 }
00294 if (subscription) {
00295 index = -1;
00296 for (i = 0; subscription->subscriptions[i]; i++) {
00297 if (!strcmp(subscription->subscriptions[i], publisher_identifier)) {
00298 index = i;
00299 }
00300 }
00301 if (index != -1) {
00302 subscription->subscriptions = (const char**)realloc(subscription->subscriptions, i * sizeof(char*));
00303 memmove(subscription->subscriptions + index, subscription->subscriptions + index + 1, (i - index) * sizeof(const char**));
00304
00305 subscription_save(subscription);
00306 }
00307 }
00308 }
00309
00310 int microfeed_configuration_is_subscribed(MicrofeedConfiguration* configuration, const char* application_identifier, const char* publisher_identifier) {
00311 int found = 0;
00312 Subscription* subscription;
00313 int i;
00314
00315 if (!(subscription = microfeed_store_get(configuration->subscriptions, application_identifier, Subscription))) {
00316 subscription = update_and_get_subscription(configuration, application_identifier);
00317 }
00318 if (subscription) {
00319 found = 0;
00320 for (i = 0; subscription->subscriptions[i]; i++) {
00321 if (!strcmp(subscription->subscriptions[i], publisher_identifier)) {
00322 found = 1;
00323 break;
00324 }
00325 }
00326 }
00327
00328 return found;
00329 }
00330
00331 const char** microfeed_configuration_get_wizards(MicrofeedConfiguration* configuration) {
00332 if (!configuration->wizards) {
00333 update_wizards(configuration);
00334 }
00335
00336 return configuration->wizards;
00337 }
00338
00339 const char* microfeed_configuration_get_wizard_name(MicrofeedConfiguration* configuration, const char* publisher_identifier) {
00340 const char* name = NULL;
00341 int index;
00342
00343 if ((index = update_and_get_wizard_index(configuration, publisher_identifier)) != -1) {
00344 name = configuration->wizard_names[index];
00345 }
00346
00347 return name;
00348 }
00349
00350 const char** microfeed_configuration_get_wizard_settings(MicrofeedConfiguration* configuration, const char* publisher_identifier) {
00351 const char** settings = NULL;
00352 int index;
00353
00354 if ((index = update_and_get_wizard_index(configuration, publisher_identifier)) != -1) {
00355 settings = configuration->wizard_settings[index];
00356 }
00357
00358 return settings;
00359
00360 }
00361
00362 static Subscription* subscription_new(const char* application_identifier, const char* filename, const char** subscription_strings) {
00363 Subscription* subscription;
00364
00365 subscription = microfeed_memory_allocate(Subscription);
00366 subscription->application_identifier = strdup(application_identifier);
00367 subscription->filename = strdup(filename);
00368 subscription->subscriptions = subscription_strings;
00369
00370 return subscription;
00371 }
00372
00373 static void subscription_free(Subscription* subscription) {
00374 int i;
00375
00376 free(subscription->application_identifier);
00377 free(subscription->filename);
00378 for (i = 0; subscription->subscriptions[i]; i++) {
00379 free((void*)subscription->subscriptions[i]);
00380 }
00381 free(subscription->subscriptions);
00382 }
00383
00384 static const char* subscription_get_application_identifier(Subscription* subscription) {
00385
00386 return subscription->application_identifier;
00387 }
00388
00389 static void subscription_save(Subscription* subscription) {
00390 char* file;
00391 char* directory;
00392 int fd;
00393 int i;
00394
00395 file = strdup(subscription->filename);
00396 directory = dirname(file);
00397 microfeed_util_create_directory_recursively(directory);
00398 free(file);
00399
00400 if ((fd = open(subscription->filename, O_WRONLY | O_CREAT | O_TRUNC, 0666)) != -1) {
00401 for (i = 0; subscription->subscriptions[i]; i++) {
00402 write(fd, subscription->subscriptions[i], strlen(subscription->subscriptions[i]));
00403 write(fd, "\n", 1);
00404 }
00405 close(fd);
00406 }
00407 }
00408
00409 static ssize_t read_line(int fd, size_t offset, char* buffer, size_t buffer_size) {
00410 ssize_t length = -1;
00411 size_t i;
00412
00413 if (lseek(fd, offset, SEEK_SET) != -1) {
00414 if ((length = read(fd, buffer, buffer_size)) > 0) {
00415 for (i = 0; i < length && buffer[i] != '\n' && buffer[i] != '\r'; i++) {
00416 }
00417 if (i == buffer_size) {
00418 length = 0;
00419 } else {
00420 buffer[i] = 0;
00421 length = i + 1;
00422 }
00423 }
00424 }
00425
00426 return length;
00427 }
00428
00429 static void get_providers(MicrofeedConfiguration* configuration, const char* directory, unsigned int* length_pointer) {
00430 DIR* dir;
00431 struct dirent* dirent;
00432 int i;
00433 int order;
00434
00435 if ((dir = opendir(directory))) {
00436 while ((dirent = readdir(dir))) {
00437 if (dirent->d_name[0] != '.') {
00438 for (i = 0; i < *length_pointer; i++) {
00439 if ((order = strcmp(configuration->providers[i], dirent->d_name)) >= 0) {
00440 break;
00441 }
00442 }
00443 if (i == *length_pointer || order != 0) {
00444 (*length_pointer)++;
00445 configuration->providers = (const char**)realloc(configuration->providers, (*length_pointer + 1) * sizeof(char*));
00446 configuration->provider_directories = (const char**)realloc(configuration->provider_directories, *length_pointer * sizeof(char*));
00447 configuration->provider_names = (const char**)realloc(configuration->provider_names, *length_pointer * sizeof(char*));
00448 configuration->provider_feeds = (const char***)realloc(configuration->provider_feeds, *length_pointer * sizeof(char**));
00449 if (i < *length_pointer - 1) {
00450 memmove(configuration->providers + i + 1, configuration->providers + i, (*length_pointer - i - 1) * sizeof(char*));
00451 memmove(configuration->provider_directories + i + 1, configuration->provider_directories + i, (*length_pointer - i - 1) * sizeof(char*));
00452 memmove(configuration->provider_names + i + 1, configuration->provider_names + i, (*length_pointer - i - 1) * sizeof(char*));
00453 memmove(configuration->provider_feeds + i + 1, configuration->provider_feeds + i, (*length_pointer - i - 1) * sizeof(char*));
00454 }
00455 configuration->providers[i] = strdup(dirent->d_name);
00456 configuration->provider_directories[i] = directory;
00457 configuration->provider_names[i] = NULL;
00458 configuration->provider_feeds[i] = NULL;
00459 configuration->providers[*length_pointer] = NULL;
00460 }
00461 }
00462 }
00463 closedir(dir);
00464 }
00465 }
00466
00467 static void get_publishers(MicrofeedConfiguration* configuration, const char* directory, unsigned int* length_pointer) {
00468 DIR* dir;
00469 struct dirent* dirent;
00470 int i;
00471 int order;
00472
00473 if ((dir = opendir(directory))) {
00474 while ((dirent = readdir(dir))) {
00475 if (dirent->d_name[0] != '.') {
00476 for (i = 0; i < *length_pointer; i++) {
00477 if ((order = strcmp(configuration->publishers[i], dirent->d_name)) >= 0) {
00478 break;
00479 }
00480 }
00481 if (i == *length_pointer || order != 0) {
00482 (*length_pointer)++;
00483 configuration->publishers = (const char**)realloc(configuration->publishers, (*length_pointer + 1) * sizeof(char*));
00484 configuration->publisher_directories = (const char**)realloc(configuration->publisher_directories, *length_pointer * sizeof(char*));
00485 if (i < *length_pointer - 1) {
00486 memmove(configuration->publishers + i + 1, configuration->publishers + i, (*length_pointer - i - 1) * sizeof(char*));
00487 memmove(configuration->publisher_directories + i + 1, configuration->publisher_directories + i, (*length_pointer - i - 1) * sizeof(char*));
00488 }
00489 configuration->publishers[i] = strdup(dirent->d_name);
00490 configuration->publisher_directories[i] = directory;
00491 configuration->publishers[*length_pointer] = NULL;
00492 }
00493 }
00494 }
00495 closedir(dir);
00496 }
00497 }
00498
00499 static void get_wizards(MicrofeedConfiguration* configuration, const char* directory, unsigned int* length_pointer) {
00500 DIR* dir;
00501 struct dirent* dirent;
00502 int i;
00503 int order;
00504
00505 if ((dir = opendir(directory))) {
00506 while ((dirent = readdir(dir))) {
00507 if (dirent->d_name[0] != '.') {
00508 for (i = 0; i < *length_pointer; i++) {
00509 if ((order = strcmp(configuration->wizards[i], dirent->d_name)) >= 0) {
00510 break;
00511 }
00512 }
00513 if (i == *length_pointer || order != 0) {
00514 (*length_pointer)++;
00515 configuration->wizards = (const char**)realloc(configuration->wizards, (*length_pointer + 1) * sizeof(char*));
00516 configuration->wizard_directories = (const char**)realloc(configuration->wizard_directories, *length_pointer * sizeof(char*));
00517 configuration->wizard_names = (const char**)realloc(configuration->wizard_names, *length_pointer * sizeof(char*));
00518 configuration->wizard_settings = (const char***)realloc(configuration->wizard_settings, *length_pointer * sizeof(char**));
00519 if (i < *length_pointer - 1) {
00520 memmove(configuration->wizards + i + 1, configuration->wizards + i, (*length_pointer - i - 1) * sizeof(char*));
00521 memmove(configuration->wizard_directories + i + 1, configuration->wizard_directories + i, (*length_pointer - i - 1) * sizeof(char*));
00522 memmove(configuration->wizard_names + i + 1, configuration->wizard_names + i, (*length_pointer - i - 1) * sizeof(char*));
00523 memmove(configuration->wizard_settings + i + 1, configuration->wizard_settings + i, (*length_pointer - i - 1) * sizeof(char*));
00524 }
00525 configuration->wizards[i] = strdup(dirent->d_name);
00526 configuration->wizard_directories[i] = directory;
00527 configuration->wizard_names[i] = NULL;
00528 configuration->wizard_settings[i] = NULL;
00529 configuration->wizards[*length_pointer] = NULL;
00530 }
00531 }
00532 }
00533 closedir(dir);
00534 }
00535 }
00536
00537 static Subscription* get_subscription(MicrofeedConfiguration* configuration, const char* application_identifier, const char* directory) {
00538 Subscription* subscription = NULL;
00539 const char** strings = NULL;
00540 char* filename;
00541 int fd;
00542 char buffer[1024];
00543 size_t offset;
00544 ssize_t length;
00545 int i;
00546
00547 strings = (const char**)malloc(sizeof(char*));
00548 strings[0] = NULL;
00549 filename = microfeed_util_string_concatenate(directory, "/", application_identifier, NULL);
00550 if ((fd = open(filename, O_RDONLY)) != -1) {
00551 offset = 0;
00552 for (i = 0; (length = read_line(fd, offset, buffer, 1024)) > 0; i++) {
00553 strings = (const char**)realloc(strings, (i + 2) * sizeof(char*));
00554 strings[i] = strdup(buffer);
00555 offset += length;
00556 }
00557 strings[i] = NULL;
00558 close(fd);
00559 }
00560 subscription = subscription_new(application_identifier, filename, strings);
00561 free(filename);
00562
00563 return subscription;
00564 }
00565
00566 static void update_providers(MicrofeedConfiguration* configuration) {
00567 unsigned int length;
00568
00569 length = 0;
00570 if (configuration->providers_environment_directory) {
00571 get_providers(configuration, configuration->providers_environment_directory, &length);
00572 }
00573 if (configuration->providers_home_directory) {
00574 get_providers(configuration, configuration->providers_home_directory, &length);
00575 }
00576 get_providers(configuration, "/usr/local/lib/microfeed/providers", &length);
00577 get_providers(configuration, "/usr/lib/microfeed/providers", &length);
00578 }
00579
00580 static void update_publishers(MicrofeedConfiguration* configuration) {
00581 unsigned int length;
00582
00583 length = 0;
00584 if (configuration->publishers_environment_directory) {
00585 get_publishers(configuration, configuration->publishers_environment_directory, &length);
00586 }
00587 if (configuration->publishers_home_directory) {
00588 get_publishers(configuration, configuration->publishers_home_directory, &length);
00589 }
00590 get_publishers(configuration, "/usr/local/lib/microfeed/publishers", &length);
00591 get_publishers(configuration, "/usr/lib/microfeed/publishers", &length);
00592 }
00593
00594 static int update_and_get_provider_index(MicrofeedConfiguration* configuration, const char* provider_identifier) {
00595 int index = -1;
00596 char* filename;
00597 int difference = -1;
00598 int fd;
00599 char buffer[1024];
00600 size_t offset;
00601 ssize_t length;
00602 int i;
00603
00604 if (!configuration->providers) {
00605 update_providers(configuration);
00606 }
00607 if (configuration->providers) {
00608 for (index = 0; configuration->providers[index] && (difference = strcmp(configuration->providers[index], provider_identifier)) < 0; index++) {
00609 }
00610 if (!difference) {
00611 if (!configuration->provider_names[index]) {
00612 filename = microfeed_util_string_concatenate(configuration->provider_directories[index], "/", provider_identifier, NULL);
00613 if ((fd = open(filename, O_RDONLY)) != -1) {
00614 offset = 0;
00615 if ((length = read_line(fd, offset, buffer, 1024)) > 0) {
00616 configuration->provider_names[index] = strdup(buffer);
00617 }
00618 offset += length;
00619 for (i = 0; (length = read_line(fd, offset, buffer, 1024)) > 0; i++) {
00620 configuration->provider_feeds[index] = (const char**)realloc(configuration->provider_feeds[index], (i + 2) * sizeof(char*));
00621 configuration->provider_feeds[index][i] = strdup(buffer);
00622 offset += length;
00623 }
00624 configuration->provider_feeds[index][i] = NULL;
00625 close(fd);
00626 }
00627 free(filename);
00628 }
00629 } else {
00630 index = -1;
00631 }
00632 }
00633
00634 return index;
00635 }
00636
00637 static int update_and_get_wizard_index(MicrofeedConfiguration* configuration, const char* provider_identifier) {
00638 int index = -1;
00639 char* filename;
00640 int difference = -1;
00641 int fd;
00642 char buffer[1024];
00643 size_t offset;
00644 ssize_t length;
00645 int i;
00646
00647 if (!configuration->wizards) {
00648 update_wizards(configuration);
00649 }
00650 if (configuration->wizards) {
00651 for (index = 0; configuration->wizards[index] && (difference = strcmp(configuration->wizards[index], provider_identifier)) < 0; index++) {
00652 }
00653 if (!difference) {
00654 if (!configuration->wizard_names[index]) {
00655 filename = microfeed_util_string_concatenate(configuration->wizard_directories[index], "/", provider_identifier, NULL);
00656 if ((fd = open(filename, O_RDONLY)) != -1) {
00657 offset = 0;
00658 if ((length = read_line(fd, offset, buffer, 1024)) > 0) {
00659 configuration->wizard_names[index] = strdup(buffer);
00660 }
00661 offset += length;
00662 for (i = 0; (length = read_line(fd, offset, buffer, 1024)) > 0; i++) {
00663 configuration->wizard_settings[index] = (const char**)realloc(configuration->wizard_settings[index], (i + 2) * sizeof(char*));
00664 configuration->wizard_settings[index][i] = strdup(buffer);
00665 offset += length;
00666 }
00667 configuration->wizard_settings[index][i] = NULL;
00668 close(fd);
00669 }
00670 free(filename);
00671 }
00672 } else {
00673 index = -1;
00674 }
00675 }
00676
00677 return index;
00678 }
00679
00680 static Subscription* update_and_get_subscription(MicrofeedConfiguration* configuration, const char* application_identifier) {
00681 Subscription* subscription = NULL;
00682
00683 if (configuration->subscribers_environment_directory) {
00684 subscription = get_subscription(configuration, application_identifier, configuration->subscribers_environment_directory);
00685 } else if (configuration->subscribers_home_directory) {
00686 subscription = get_subscription(configuration, application_identifier, configuration->subscribers_home_directory);
00687 }
00688
00689 return subscription;
00690 }
00691
00692 static void update_wizards(MicrofeedConfiguration* configuration) {
00693 unsigned int length;
00694
00695 length = 0;
00696 if (configuration->wizards_environment_directory) {
00697 get_wizards(configuration, configuration->wizards_environment_directory, &length);
00698 }
00699 if (configuration->wizards_home_directory) {
00700 get_wizards(configuration, configuration->wizards_home_directory, &length);
00701 }
00702 get_wizards(configuration, "/usr/local/lib/microfeed/wizards", &length);
00703 get_wizards(configuration, "/usr/lib/microfeed/wizards", &length);
00704 }