00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include
00020 #include
00021 #include
00022 #include
00023 #ifdef WIN32
00024 #include
00025 #include
00026 #include
00027 #endif
00028
00029 #include "configuration.h"
00030 #include "nntpgrab_internal.h"
00031
00032 typedef struct ConfigurationClass ConfigurationClass;
00033
00034 Configuration *configuration_get_object(void);
00035 GType configuration_get_type (void);
00036
00037 typedef struct _config_server_details
00038 {
00039 GList *groups;
00040 } ConfigServerDetails;
00041
00042 struct Configuration
00043 {
00044 GObject parent;
00045
00046 GStaticRWLock rwlock;
00047 GList *servers;
00048 GHashTable *group_details;
00049
00050 ConfigOpts opts;
00051 };
00052
00053 struct ConfigurationClass
00054 {
00055 GObjectClass parent;
00056 };
00057
00058 enum
00059 {
00060 CONFIG_CHANGED_SIGNAL,
00061 LAST_SIGNAL
00062 };
00063
00064 static guint signals[LAST_SIGNAL] = { 0 };
00065
00066 G_DEFINE_TYPE(Configuration, configuration, G_TYPE_OBJECT)
00067
00068 static void
00069 group_details_free_func(gpointer data)
00070 {
00071 g_slice_free(ConfigGroupInfo, data);
00072 }
00073
00074 static void
00075 configuration_init (Configuration *obj)
00076 {
00077 g_static_rw_lock_init(&obj->rwlock);
00078
00079 obj->servers = NULL;
00080 obj->group_details = g_hash_table_new_full(g_str_hash, g_str_equal, NULL, group_details_free_func);
00081 }
00082
00083 static void
00084 configuration_finalize (GObject *obj)
00085 {
00086 char *errmsg;
00087 Configuration *config = CONFIGURATION(obj);
00088 GList *list;
00089
00090 if (!(configuration_save(config, &errmsg))) {
00091 nntpgrab_core_emit_warning(errmsg);
00092 g_free(errmsg);
00093 }
00094
00095 g_static_rw_lock_writer_lock(&config->rwlock);
00096
00097 list = config->servers;
00098 while (list) {
00099 g_slice_free(ConfigServer, list->data);
00100 list = g_list_next(list);
00101 }
00102 g_list_free(config->servers);
00103
00104 g_hash_table_destroy(config->group_details);
00105
00106 g_static_rw_lock_writer_unlock(&config->rwlock);
00107 g_static_rw_lock_free(&config->rwlock);
00108 }
00109
00110 static void
00111 configuration_class_init (ConfigurationClass *klass)
00112 {
00113 GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
00114
00115 gobject_class->finalize = configuration_finalize;
00116
00117 signals[CONFIG_CHANGED_SIGNAL] = g_signal_new ("config_changed",
00118 G_OBJECT_CLASS_TYPE (klass),
00119 G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED,
00120 0,
00121 NULL, NULL,
00122 g_cclosure_marshal_VOID__INT,
00123 G_TYPE_NONE, 1, G_TYPE_INT);
00124 }
00125
00126 Configuration *
00127 configuration_new(char **errmsg, char **warnings)
00128 {
00129 Configuration *config = g_object_new(CONFIGURATION_TYPE_OBJECT, NULL);
00130
00131 if (!configuration_load(config, errmsg)) {
00132
00133
00134 g_free(*errmsg);
00135 *errmsg = NULL;
00136
00137 if (warnings) {
00138 *warnings = g_strdup(_("Configuration file for the NNTPGrab backend could not be loaded. Default configuration file is now created"));
00139 }
00140 }
00141
00142 return config;
00143 }
00144
00145 void
00146 configuration_destroy(Configuration *obj)
00147 {
00148 g_object_unref(obj);
00149 }
00150
00151
00159 GList *
00160 configuration_get_avail_servers(Configuration *obj)
00161 {
00162 Configuration *config = CONFIGURATION(obj);
00163 GList *list;
00164 GList *ret = NULL;
00165
00166 g_static_rw_lock_reader_lock(&config->rwlock);
00167
00168 list = config->servers;
00169 while (list) {
00170 ConfigServer *server = list->data;
00171
00172 ret = g_list_append(ret, g_strdup(server->servername));
00173
00174 list = g_list_next(list);
00175 }
00176
00177 g_static_rw_lock_reader_unlock(&config->rwlock);
00178
00179 return ret;
00180 }
00181
00188 void
00189 configuration_free_avail_servers(Configuration *obj, GList *servers)
00190 {
00191 GList *list;
00192
00193 list = servers;
00194 while (list) {
00195 g_free(list->data);
00196 list = g_list_next(list);
00197 }
00198
00199 g_list_free(servers);
00200 }
00201
00209 ConfigServer *
00210 configuration_get_server_info(Configuration *obj, const char *servername)
00211 {
00212 Configuration *config = CONFIGURATION(obj);
00213 GList *list;
00214
00215 g_static_rw_lock_reader_lock(&config->rwlock);
00216
00217 list = config->servers;
00218 while (list) {
00219 ConfigServer *server = list->data;
00220
00221 if (!strcmp(server->servername, servername)) {
00222 ConfigServer *ret = g_slice_new0(ConfigServer);
00223
00224 memcpy(ret, server, sizeof(ConfigServer));
00225
00226 g_static_rw_lock_reader_unlock(&config->rwlock);
00227
00228 return ret;
00229 }
00230
00231 list = g_list_next(list);
00232 }
00233
00234 g_static_rw_lock_reader_unlock(&config->rwlock);
00235
00236 return NULL;
00237 }
00238
00246 gboolean
00247 configuration_add_server(Configuration *obj, ConfigServer new_server)
00248 {
00249 Configuration *config = CONFIGURATION(obj);
00250 ConfigServer *server;
00251 GList *list;
00252
00253
00254 g_assert(new_server.port > 0 && new_server.port 00255 g_assert(new_server.max_threads > 0);
00256
00257 if (!strcmp(new_server.servername, "options")) {
00258 return FALSE;
00259 }
00260
00261
00262 g_static_rw_lock_reader_lock(&config->rwlock);
00263
00264 list = config->servers;
00265 while (list) {
00266 server = list->data;
00267
00268 if (!strcmp(new_server.servername, server->servername)) {
00269
00270 g_static_rw_lock_reader_unlock(&config->rwlock);
00271 return FALSE;
00272 }
00273
00274 list = g_list_next(list);
00275 }
00276
00277 g_static_rw_lock_reader_unlock(&config->rwlock);
00278
00279
00280 g_static_rw_lock_writer_lock(&config->rwlock);
00281
00282 server = g_slice_new0(ConfigServer);
00283 memcpy(server, &new_server, sizeof(ConfigServer));
00284 config->servers = g_list_append(config->servers, server);
00285
00286 g_static_rw_lock_writer_unlock(&config->rwlock);
00287
00288
00289 g_signal_emit (config, signals[CONFIG_CHANGED_SIGNAL], 0, CONFIG_CHANGED_SERVER_ADDED);
00290
00291 return TRUE;
00292 }
00293
00301 gboolean
00302 configuration_del_server(Configuration *obj, const char *servername)
00303 {
00304 Configuration *config = CONFIGURATION(obj);
00305 ConfigServer *server;
00306 GList *list;
00307
00308
00309 g_static_rw_lock_reader_lock(&config->rwlock);
00310
00311 list = config->servers;
00312 while (list) {
00313 server = list->data;
00314
00315 if (!strcmp(servername, server->servername)) {
00316
00317 g_static_rw_lock_reader_unlock(&config->rwlock);
00318
00319 g_static_rw_lock_writer_lock(&config->rwlock);
00320
00321 g_slice_free(ConfigServer, server);
00322 config->servers = g_list_remove(config->servers, server);
00323
00324 g_static_rw_lock_writer_unlock(&config->rwlock);
00325
00326
00327 g_signal_emit (config, signals[CONFIG_CHANGED_SIGNAL], 0, CONFIG_CHANGED_SERVER_DELETED);
00328
00329 return TRUE;
00330 }
00331
00332 list = g_list_next(list);
00333 }
00334
00335 g_static_rw_lock_reader_unlock(&config->rwlock);
00336
00337 return FALSE;
00338 }
00339
00348 gboolean
00349 configuration_edit_server(Configuration *obj, const char *servername, ConfigServer new_server)
00350 {
00351 Configuration *config = CONFIGURATION(obj);
00352 ConfigServer *server;
00353 GList *list;
00354
00355 if (!strcmp(new_server.servername, "options")) {
00356 return FALSE;
00357 }
00358
00359
00360 g_static_rw_lock_reader_lock(&config->rwlock);
00361
00362 list = config->servers;
00363 while (list) {
00364 server = list->data;
00365
00366 if (!strcmp(servername, server->servername)) {
00367
00368 g_static_rw_lock_reader_unlock(&config->rwlock);
00369
00370 g_static_rw_lock_writer_lock(&config->rwlock);
00371
00372
00373 memcpy(server, &new_server, sizeof(ConfigServer));
00374
00375 g_static_rw_lock_writer_unlock(&config->rwlock);
00376
00377
00378 g_signal_emit (config, signals[CONFIG_CHANGED_SIGNAL], 0, CONFIG_CHANGED_SERVER_ADDED);
00379
00380
00381 return TRUE;
00382 }
00383
00384 list = g_list_next(list);
00385 }
00386
00387 g_static_rw_lock_reader_unlock(&config->rwlock);
00388
00389 return FALSE;
00390 }
00391
00398 ConfigOpts
00399 configuration_get_opts(Configuration *obj)
00400 {
00401 Configuration *config = CONFIGURATION(obj);
00402 ConfigOpts ret;
00403
00404 g_static_rw_lock_reader_lock(&config->rwlock);
00405
00406 ret = config->opts;
00407
00408 g_static_rw_lock_reader_unlock(&config->rwlock);
00409
00410 return ret;
00411 }
00412
00419 void
00420 configuration_set_opts(Configuration *obj, ConfigOpts opts)
00421 {
00422 Configuration *config = CONFIGURATION(obj);
00423
00424 g_static_rw_lock_writer_lock(&config->rwlock);
00425
00426
00427 #ifdef WIN32
00428 if (strlen(opts.download_directory) == 2 && opts.download_directory[1] == ':') {
00429 opts.download_directory[2] = '\\';
00430 opts.download_directory[3] = '\0';
00431 }
00432
00433 if (strlen(opts.temp_directory) == 2 && opts.temp_directory[1] == ':') {
00434 opts.temp_directory[2] = '\\';
00435 opts.temp_directory[3] = '\0';
00436 }
00437 #endif
00438
00439 config->opts = opts;
00440
00441 g_static_rw_lock_writer_unlock(&config->rwlock);
00442
00443
00444 g_signal_emit (config, signals[CONFIG_CHANGED_SIGNAL], 0, CONFIG_CHANGED_OPTS_CHANGED);
00445 }
00446
00456 ConfigGroupInfo
00457 configuration_get_newsgroup_info(Configuration *obj, const char *servername, const char *newsgroup)
00458 {
00459 ConfigGroupInfo ret;
00460 ConfigGroupInfo *info;
00461 Configuration *config = CONFIGURATION(obj);
00462 char *hash;
00463
00464 g_static_rw_lock_reader_lock(&config->rwlock);
00465
00466 hash = g_strdup_printf("%s_%s", servername, newsgroup);
00467 info = g_hash_table_lookup(config->group_details, hash);
00468 g_free(hash);
00469
00470 if (info) {
00471 memcpy(&ret, info, sizeof(ConfigGroupInfo));
00472 } else {
00473 memset(&ret, 0, sizeof(ConfigGroupInfo));
00474 strncpy((char *) ret.newsgroup, newsgroup, sizeof(ret.newsgroup));
00475 }
00476
00477 g_static_rw_lock_reader_unlock(&config->rwlock);
00478
00479 return ret;
00480 }
00481
00490 void
00491 configuration_set_newsgroup_info(Configuration *obj, const char *servername, const char *newsgroup, ConfigGroupInfo info)
00492 {
00493 Configuration *config = CONFIGURATION(obj);
00494 ConfigGroupInfo *info_new;
00495 char *hash;
00496
00497 g_static_rw_lock_writer_lock(&config->rwlock);
00498
00499 info_new = g_slice_new(ConfigGroupInfo);
00500 memcpy(info_new, &info, sizeof(ConfigGroupInfo));
00501
00502 hash = g_strdup_printf("%s_%s", servername, newsgroup);
00503 g_hash_table_replace(config->group_details, hash, info_new);
00504 g_free(hash);
00505
00506 g_static_rw_lock_writer_unlock(&config->rwlock);
00507 }
00508
00516 gboolean
00517 configuration_load(Configuration *obj, char **errmsg)
00518 {
00519 Configuration *config = CONFIGURATION(obj);
00520 GKeyFile *keyfile;
00521 GError *err = NULL;
00522 char *filename;
00523 char **groups;
00524 int i;
00525 GList *list;
00526
00527 g_static_rw_lock_writer_lock(&config->rwlock);
00528
00529
00530 list = config->servers;
00531 while (list) {
00532 ConfigServer *server = list->data;
00533
00534 g_free(server);
00535
00536 list = g_list_next(list);
00537 }
00538
00539 g_list_free(config->servers);
00540 config->servers = NULL;
00541
00542
00543 filename = g_build_filename(g_get_user_config_dir(), "NNTPGrab", "nntpgrab.conf", NULL);
00544 keyfile = g_key_file_new();
00545 if (!g_key_file_load_from_file(keyfile, filename, G_KEY_FILE_NONE, &err)) {
00546 char *tmp;
00547
00548 if (errmsg) {
00549 *errmsg = g_strdup_printf(_("configuration_load(): Error while opening file '%s'\n%s"), filename, err->message);
00550 }
00551
00552 g_free(filename);
00553 g_error_free(err);
00554 g_key_file_free(keyfile);
00555
00556
00557 #ifdef WIN32
00558 tmp = g_build_path(G_DIR_SEPARATOR_S, g_get_user_special_dir(G_USER_DIRECTORY_DOCUMENTS), "NNTPGrab", "Downloads", NULL);
00559 #else
00560 tmp = g_build_path(G_DIR_SEPARATOR_S, g_get_home_dir(), "NNTPGrab", "Downloads", NULL);
00561 #endif
00562 strncpy(config->opts.download_directory, tmp, sizeof(config->opts.download_directory));
00563 g_mkdir_with_parents(tmp, 0700);
00564 g_free(tmp);
00565
00566 #ifdef WIN32
00567 tmp = g_build_path(G_DIR_SEPARATOR_S, g_get_user_special_dir(G_USER_DIRECTORY_DOCUMENTS), "NNTPGrab", "Temp", NULL);
00568 #else
00569 tmp = g_build_path(G_DIR_SEPARATOR_S, g_get_home_dir(), "NNTPGrab", "Temp", NULL);
00570 #endif
00571 strncpy(config->opts.temp_directory, tmp, sizeof(config->opts.temp_directory));
00572 g_mkdir_with_parents(tmp, 0700);
00573 g_free(tmp);
00574
00575 g_static_rw_lock_writer_unlock(&config->rwlock);
00576
00577 return FALSE;
00578 }
00579
00580 g_free(filename);
00581
00582 groups = g_key_file_get_groups(keyfile, NULL);
00583 i = 0;
00584 while (groups[i]) {
00585 char *value;
00586 ConfigServer *server;
00587
00588 if (!strcmp(groups[i], "options")) {
00589 char *tmp;
00590
00591 tmp = g_key_file_get_string(keyfile, groups[i], "download_directory", NULL);
00592 if (tmp) {
00593 strncpy(config->opts.download_directory, tmp, sizeof(config->opts.download_directory));
00594 g_free(tmp);
00595 }
00596
00597 tmp = g_key_file_get_string(keyfile, groups[i], "temp_directory", NULL);
00598 if (tmp) {
00599 strncpy(config->opts.temp_directory, tmp, sizeof(config->opts.temp_directory));
00600 g_free(tmp);
00601 }
00602
00603 config->opts.enable_intelligent_par2_downloading = g_key_file_get_boolean(keyfile, groups[i], "enable_intelligent_par2_downloading", NULL);
00604
00605 i++;
00606 continue;
00607 }
00608
00609 server = g_slice_new(ConfigServer);
00610
00611 strncpy(server->servername, groups[i], sizeof(server->servername));
00612
00613 value = g_key_file_get_string(keyfile, groups[i], "hostname", NULL);
00614 if (!value) {
00615 g_print(_("No hostname could be found for servername '%s'. Ignoring server\n"), groups[i]);
00616 i++;
00617 continue;
00618 }
00619
00620 strncpy(server->hostname, value, sizeof(server->hostname));
00621 g_free(value);
00622
00623 server->port = g_key_file_get_integer(keyfile, groups[i], "port", NULL);
00624
00625 value = g_key_file_get_string(keyfile, groups[i], "username", NULL);
00626 if (value) {
00627 strncpy(server->username, value, sizeof(server->username));
00628 g_free(value);
00629 }
00630
00631 value = g_key_file_get_string(keyfile, groups[i], "password", NULL);
00632 if (value) {
00633 strncpy(server->password, value, sizeof(server->password));
00634 g_free(value);
00635 }
00636
00637 server->max_threads = g_key_file_get_integer(keyfile, groups[i], "max_threads", NULL);
00638 server->use_ssl = g_key_file_get_boolean(keyfile, groups[i], "use_ssl", NULL);
00639
00640
00641 if (!g_key_file_has_key(keyfile, groups[i], "priority", NULL)) {
00642 server->priority = SERVER_PRIORITY_NORMAL;
00643 } else {
00644 server->priority = g_key_file_get_integer(keyfile, groups[i], "priority", NULL);
00645 }
00646
00647 if (!g_key_file_has_key(keyfile, groups[i], "enabled", NULL)) {
00648 server->enabled = TRUE;
00649 } else {
00650 server->enabled = g_key_file_get_boolean(keyfile, groups[i], "enabled", NULL);
00651 }
00652
00653 config->servers = g_list_append(config->servers, server);
00654
00655 i++;
00656 }
00657
00658 g_strfreev(groups);
00659
00660 g_key_file_free(keyfile);
00661
00662
00663 #ifdef WIN32
00664 if (strlen(config->opts.download_directory) == 2) {
00665 config->opts.download_directory[2] = '\\';
00666 config->opts.download_directory[3] = '\0';
00667 }
00668
00669 if (strlen(config->opts.temp_directory) == 2) {
00670 config->opts.temp_directory[2] = '\\';
00671 config->opts.temp_directory[3] = '\0';
00672 }
00673 #endif
00674
00675 if (!g_file_test(config->opts.download_directory, G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR)) {
00676 char *tmp;
00677
00678 #ifdef WIN32
00679 tmp = g_build_path(G_DIR_SEPARATOR_S, g_get_user_special_dir(G_USER_DIRECTORY_DOCUMENTS), "NNTPGrab", "Downloads", NULL);
00680 #else
00681 tmp = g_build_path(G_DIR_SEPARATOR_S, g_get_home_dir(), "NNTPGrab", "Downloads", NULL);
00682 #endif
00683 strncpy(config->opts.download_directory, tmp, sizeof(config->opts.download_directory));
00684 g_mkdir_with_parents(tmp, 0700);
00685 g_free(tmp);
00686 }
00687
00688 if (!g_file_test(config->opts.temp_directory, G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR)) {
00689 char *tmp;
00690
00691 #ifdef WIN32
00692 tmp = g_build_path(G_DIR_SEPARATOR_S, g_get_user_special_dir(G_USER_DIRECTORY_DOCUMENTS), "NNTPGrab", "Temp", NULL);
00693 #else
00694 tmp = g_build_path(G_DIR_SEPARATOR_S, g_get_home_dir(), "NNTPGrab", "Temp", NULL);
00695 #endif
00696 strncpy(config->opts.temp_directory, tmp, sizeof(config->opts.temp_directory));
00697 g_mkdir_with_parents(tmp, 0700);
00698 g_free(tmp);
00699 }
00700
00701 g_static_rw_lock_writer_unlock(&config->rwlock);
00702
00703
00704 g_signal_emit (config, signals[CONFIG_CHANGED_SIGNAL], 0, CONFIG_CHANGED_SERVER_ADDED | CONFIG_CHANGED_SERVER_DELETED);
00705
00706 return TRUE;
00707 }
00708
00716 gboolean
00717 configuration_save(Configuration *obj, char **errmsg)
00718 {
00719 Configuration *config = CONFIGURATION(obj);
00720 GKeyFile *keyfile;
00721 GError *err = NULL;
00722 char *filename;
00723 char *dirname;
00724 char *contents;
00725 GList *list;
00726
00727 g_static_rw_lock_reader_lock(&config->rwlock);
00728
00729 keyfile = g_key_file_new();
00730
00731 g_key_file_set_string(keyfile, "options", "download_directory", config->opts.download_directory);
00732 g_key_file_set_string(keyfile, "options", "temp_directory", config->opts.temp_directory);
00733 g_key_file_set_boolean(keyfile, "options", "enable_intelligent_par2_downloading", config->opts.enable_intelligent_par2_downloading);
00734
00735 list = config->servers;
00736 while (list) {
00737 ConfigServer *server = list->data;
00738
00739 g_key_file_set_string(keyfile, server->servername, "hostname", server->hostname);
00740 g_key_file_set_integer(keyfile, server->servername, "port", server->port);
00741 g_key_file_set_string(keyfile, server->servername, "username", server->username);
00742 g_key_file_set_string(keyfile, server->servername, "password", server->password);
00743 g_key_file_set_integer(keyfile, server->servername, "max_threads", server->max_threads);
00744 g_key_file_set_boolean(keyfile, server->servername, "use_ssl", server->use_ssl);
00745 g_key_file_set_integer(keyfile, server->servername, "priority", server->priority);
00746 g_key_file_set_boolean(keyfile, server->servername, "enabled", server->enabled);
00747
00748 list = g_list_next(list);
00749 }
00750
00751 contents = g_key_file_to_data(keyfile, NULL, &err);
00752 if (!contents) {
00753 if (errmsg) {
00754 *errmsg = g_strdup(err->message);
00755 }
00756
00757 g_error_free(err);
00758 g_free(contents);
00759 g_key_file_free(keyfile);
00760 g_static_rw_lock_reader_unlock(&config->rwlock);
00761
00762 return FALSE;
00763 }
00764
00765
00766 dirname = g_build_path(G_DIR_SEPARATOR_S, g_get_user_config_dir(), "NNTPGrab", NULL);
00767 g_mkdir_with_parents(dirname, 0700);
00768 g_free(dirname);
00769
00770 filename = g_build_filename(g_get_user_config_dir(), "NNTPGrab", "nntpgrab.conf", NULL);
00771
00772 if (!g_file_set_contents(filename, contents, -1, &err)) {
00773 if (errmsg) {
00774 *errmsg = g_strdup_printf(_("configuration_save(): Error while opening file '%s'\n%s"), filename, err->message);
00775 }
00776
00777 g_error_free(err);
00778 g_free(contents);
00779 g_free(filename);
00780 g_key_file_free(keyfile);
00781 g_static_rw_lock_reader_unlock(&config->rwlock);
00782
00783 return FALSE;
00784 }
00785
00786 g_free(contents);
00787 g_free(filename);
00788 g_key_file_free(keyfile);
00789 g_static_rw_lock_reader_unlock(&config->rwlock);
00790
00791 return TRUE;
00792 }
00793
00794 static gint
00795 sort_folders_func(gconstpointer a, gconstpointer b)
00796 {
00797 const ConfigFolder *folderA = a;
00798 const ConfigFolder *folderB = b;
00799
00800 if (a == NULL) {
00801 return 1;
00802 }
00803
00804 if (b == NULL) {
00805 return 1;
00806 }
00807
00808 return g_strcasecmp(folderA->folder, folderB->folder);
00809 }
00810
00820 gboolean
00821 configuration_get_folder_listing(Configuration *obj, const char *parent, GList **folders)
00822 {
00823 GDir *dir;
00824 const char *filename;
00825 #ifdef WIN32
00826 char *tmp;
00827 #endif
00828
00829 g_assert(folders);
00830
00831 *folders = NULL;
00832
00833 if (!parent) {
00834 #ifdef WIN32
00835 DWORD logicalDrives = GetLogicalDrives() 00836 int i = 1;
00837 char driveLetter = 'A';
00838
00839 while(driveLetter 'Z') {
00840 char *path;
00841
00842 if(logicalDrives & (int)pow(2,i)) {
00843 GDir *dir;
00844 ConfigFolder *folder = g_slice_new0(ConfigFolder);
00845
00846 path = g_strdup_printf("%c:\\", driveLetter);
00847
00848 #ifdef WIN32
00849
00850
00851 if (!PathFileExistsA(path)) {
00852 i++;
00853 driveLetter++;
00854 g_free(folder);
00855 g_free(path);
00856 continue;
00857 }
00858 #endif
00859
00860 dir = g_dir_open(path, 0, NULL);
00861
00862 folder->has_subfolders = FALSE;
00863
00864 if (dir) {
00865 const char *filename;
00866 while ((filename = g_dir_read_name(dir))) {
00867 char *path2 = g_build_filename(path, filename, NULL);
00868 if (g_file_test(path2, G_FILE_TEST_IS_DIR)) {
00869 folder->has_subfolders = TRUE;
00870 }
00871 g_free(path2);
00872 }
00873 g_dir_close(dir);
00874 }
00875
00876
00877 path[strlen(path) - 1] = '\0';
00878 strncpy(folder->folder, path, sizeof(folder->folder) - 1);
00879
00880 *folders = g_list_append(*folders, folder);
00881
00882 g_free(path);
00883 }
00884
00885 i++;
00886 driveLetter++;
00887 }
00888
00889 return TRUE;
00890 #else
00891 ConfigFolder *folder = g_slice_new0(ConfigFolder);
00892 folder->has_subfolders = TRUE;
00893 folder->folder[0] = '/';
00894 folder->folder[1] = '\0';
00895 *folders = g_list_append(*folders, folder);
00896 return TRUE;
00897 #endif
00898 }
00899
00900 #ifdef WIN32
00901 if (strlen(parent) == 2) {
00902 tmp = g_strdup_printf("%s\\", parent);
00903 } else {
00904 tmp = g_strdup(parent);
00905 }
00906 dir = g_dir_open(tmp, 0, NULL);
00907 g_free(tmp);
00908 #else
00909 dir = g_dir_open(parent, 0, NULL);
00910 #endif
00911 if (!dir) {
00912 return FALSE;
00913 }
00914
00915 while ((filename = g_dir_read_name(dir))) {
00916
00917 char *path = g_build_filename(parent, filename, NULL);
00918 if (g_file_test(path, G_FILE_TEST_IS_DIR)) {
00919 GDir *dir2 = g_dir_open(path, 0, NULL);
00920 if (dir2) {
00921 ConfigFolder *folder = g_slice_new0(ConfigFolder);
00922 const char *filename2;
00923
00924 folder->has_subfolders = FALSE;
00925 while ((filename2 = g_dir_read_name(dir2))) {
00926 char *path2 = g_build_filename(parent, filename, filename2, NULL);
00927 if (g_file_test(path2, G_FILE_TEST_IS_DIR)) {
00928 folder->has_subfolders = TRUE;
00929 g_free(path2);
00930 break;
00931 }
00932 g_free(path2);
00933 }
00934 g_dir_close(dir2);
00935
00936 strncpy(folder->folder, filename, sizeof(folder->folder) - 1);
00937
00938 *folders = g_list_append(*folders, folder);
00939 }
00940 }
00941 g_free(path);
00942 }
00943
00944 g_dir_close(dir);
00945
00946 *folders = g_list_sort(*folders, sort_folders_func);
00947
00948 return TRUE;
00949 }
00950
00951 void
00952 configuration_free_folder_listing(Configuration *obj, GList *folders)
00953 {
00954 GList *list = folders;
00955 while (list) {
00956 g_slice_free(ConfigFolder, list->data);
00957 list = g_list_next(list);
00958 }
00959 g_list_free(folders);
00960 }