diff options
author | Christian Grothoff <christian@grothoff.org> | 2012-01-09 16:46:39 +0000 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2012-01-09 16:46:39 +0000 |
commit | 474f9794b40f029e45e61cbfa2dd8a781a811ae1 (patch) | |
tree | ee7878cb19e13f87b8a1c9000a6ae65be040cb75 | |
parent | 0b2c209a381b00fcd8ac982b4ea0899411deaf8b (diff) | |
download | gnunet-gtk-474f9794b40f029e45e61cbfa2dd8a781a811ae1.tar.gz gnunet-gtk-474f9794b40f029e45e61cbfa2dd8a781a811ae1.zip |
-LRN: make directory scanner run via scheduler
-rw-r--r-- | src/fs/gnunet-fs-gtk-event_handler.c | 16 | ||||
-rw-r--r-- | src/fs/gnunet-fs-gtk-main_window_adv_pseudonym.c | 2 | ||||
-rw-r--r-- | src/fs/gnunet-fs-gtk-main_window_file_publish.c | 222 |
3 files changed, 228 insertions, 12 deletions
diff --git a/src/fs/gnunet-fs-gtk-event_handler.c b/src/fs/gnunet-fs-gtk-event_handler.c index 4658d23e..11a73be4 100644 --- a/src/fs/gnunet-fs-gtk-event_handler.c +++ b/src/fs/gnunet-fs-gtk-event_handler.c | |||
@@ -1215,11 +1215,17 @@ handle_publish_stop (struct PublishEntry *ent) | |||
1215 | /* get piter from parent */ | 1215 | /* get piter from parent */ |
1216 | path = gtk_tree_row_reference_get_path (ent->rr); | 1216 | path = gtk_tree_row_reference_get_path (ent->rr); |
1217 | tm = gtk_tree_row_reference_get_model (ent->rr); | 1217 | tm = gtk_tree_row_reference_get_model (ent->rr); |
1218 | if (TRUE != gtk_tree_model_get_iter (tm, &iter, path)) | 1218 | /* This is a child of a directory, and we've had that directory |
1219 | GNUNET_break (0); | 1219 | * freed already |
1220 | else | 1220 | */ |
1221 | (void) gtk_tree_store_remove (GTK_TREE_STORE (tm), &iter); | 1221 | if (path != NULL) |
1222 | gtk_tree_path_free (path); | 1222 | { |
1223 | if (TRUE != gtk_tree_model_get_iter (tm, &iter, path)) | ||
1224 | GNUNET_break (0); | ||
1225 | else | ||
1226 | (void) gtk_tree_store_remove (GTK_TREE_STORE (tm), &iter); | ||
1227 | gtk_tree_path_free (path); | ||
1228 | } | ||
1223 | } | 1229 | } |
1224 | gtk_tree_row_reference_free (ent->rr); | 1230 | gtk_tree_row_reference_free (ent->rr); |
1225 | if (ent->uri != NULL) | 1231 | if (ent->uri != NULL) |
diff --git a/src/fs/gnunet-fs-gtk-main_window_adv_pseudonym.c b/src/fs/gnunet-fs-gtk-main_window_adv_pseudonym.c index 50fdf4d1..b3075eb1 100644 --- a/src/fs/gnunet-fs-gtk-main_window_adv_pseudonym.c +++ b/src/fs/gnunet-fs-gtk-main_window_adv_pseudonym.c | |||
@@ -203,7 +203,7 @@ GNUNET_GTK_select_pseudonym_dialog_response_cb (GtkDialog * dialog, | |||
203 | nds->bo.anonymity_level = 1; | 203 | nds->bo.anonymity_level = 1; |
204 | nds->fip = | 204 | nds->fip = |
205 | GNUNET_FS_file_information_create_empty_directory (NULL, NULL, NULL, meta, | 205 | GNUNET_FS_file_information_create_empty_directory (NULL, NULL, NULL, meta, |
206 | &nds->bo); | 206 | &nds->bo, NULL); |
207 | GNUNET_CONTAINER_meta_data_destroy (meta); | 207 | GNUNET_CONTAINER_meta_data_destroy (meta); |
208 | GNUNET_FS_GTK_edit_publish_dialog (transient, nds->do_index, | 208 | GNUNET_FS_GTK_edit_publish_dialog (transient, nds->do_index, |
209 | nds->short_fn, nds->bo, nds->fip, FALSE, anon_liststore, | 209 | nds->short_fn, nds->bo, nds->fip, FALSE, anon_liststore, |
diff --git a/src/fs/gnunet-fs-gtk-main_window_file_publish.c b/src/fs/gnunet-fs-gtk-main_window_file_publish.c index 6791e61b..ee74ec64 100644 --- a/src/fs/gnunet-fs-gtk-main_window_file_publish.c +++ b/src/fs/gnunet-fs-gtk-main_window_file_publish.c | |||
@@ -321,7 +321,7 @@ create_dir_at_iter (struct MainPublishingDialogContext *ctx, const char *name, | |||
321 | row_reference = gtk_tree_row_reference_new (ctx->file_info_treemodel, path); | 321 | row_reference = gtk_tree_row_reference_new (ctx->file_info_treemodel, path); |
322 | gtk_tree_path_free (path); | 322 | gtk_tree_path_free (path); |
323 | fi = GNUNET_FS_file_information_create_empty_directory | 323 | fi = GNUNET_FS_file_information_create_empty_directory |
324 | (GNUNET_FS_GTK_get_fs_handle (), row_reference, NULL, meta, bo); | 324 | (GNUNET_FS_GTK_get_fs_handle (), row_reference, NULL, meta, bo, name); |
325 | GNUNET_CONTAINER_meta_data_destroy (meta); | 325 | GNUNET_CONTAINER_meta_data_destroy (meta); |
326 | gtk_tree_store_set (GTK_TREE_STORE (ctx->file_info_treemodel), pos, 0, MARKER_DIR_FILE_SIZE, 1, (gboolean) GNUNET_NO, | 326 | gtk_tree_store_set (GTK_TREE_STORE (ctx->file_info_treemodel), pos, 0, MARKER_DIR_FILE_SIZE, 1, (gboolean) GNUNET_NO, |
327 | 2, name, 3, (guint) bo->anonymity_level, 4, | 327 | 2, name, 3, (guint) bo->anonymity_level, 4, |
@@ -391,6 +391,29 @@ struct AddDirContext | |||
391 | GtkTreeIter *parent; | 391 | GtkTreeIter *parent; |
392 | 392 | ||
393 | /** | 393 | /** |
394 | * Pointer to the context of the parent directory, or NULL | ||
395 | * for top-level. | ||
396 | */ | ||
397 | struct AddDirContext *parent_ctx; | ||
398 | |||
399 | /** | ||
400 | * Directory iterator of the parent directory, or NULL | ||
401 | * for top-level. | ||
402 | */ | ||
403 | struct GNUNET_DISK_DirectoryIterator *parent_iter; | ||
404 | |||
405 | /** | ||
406 | * Filename parent directory was processing (filename of THIS directory) | ||
407 | * when it started child directory iterator. NULL for top-level. | ||
408 | */ | ||
409 | char *parent_filename; | ||
410 | |||
411 | /** | ||
412 | * Publication data for this directory. | ||
413 | */ | ||
414 | struct PublishData *pd; | ||
415 | |||
416 | /** | ||
394 | * Master publication dialog context (used to access treestore) | 417 | * Master publication dialog context (used to access treestore) |
395 | */ | 418 | */ |
396 | struct MainPublishingDialogContext *ctx; | 419 | struct MainPublishingDialogContext *ctx; |
@@ -585,7 +608,7 @@ add_entry_to_ts (GtkTreeStore * ts, GtkTreeIter * iter, const char *filename, | |||
585 | GNUNET_FS_uri_ksk_add_keyword (ksk_uri, GNUNET_FS_DIRECTORY_MIME, | 608 | GNUNET_FS_uri_ksk_add_keyword (ksk_uri, GNUNET_FS_DIRECTORY_MIME, |
586 | GNUNET_NO); | 609 | GNUNET_NO); |
587 | fi = GNUNET_FS_file_information_create_empty_directory | 610 | fi = GNUNET_FS_file_information_create_empty_directory |
588 | (GNUNET_FS_GTK_get_fs_handle (), row_reference, ksk_uri, meta, bo); | 611 | (GNUNET_FS_GTK_get_fs_handle (), row_reference, ksk_uri, meta, bo, filename); |
589 | } | 612 | } |
590 | else | 613 | else |
591 | { | 614 | { |
@@ -796,13 +819,188 @@ scan_directory (void *cls, const char *filename) | |||
796 | return GNUNET_OK; | 819 | return GNUNET_OK; |
797 | } | 820 | } |
798 | 821 | ||
822 | static void | ||
823 | add_dir_callback (void *cls, struct GNUNET_DISK_DirectoryIterator * di, | ||
824 | const char *filename, const char *dirname); | ||
825 | |||
799 | 826 | ||
800 | static void | 827 | static void |
801 | add_dir_finish (struct AddDirContext *scan_ctx) | 828 | child_dir_finished_publishing (struct AddDirContext *adc) |
802 | { | 829 | { |
803 | GNUNET_free (scan_ctx); | 830 | const char *ss; |
831 | const char *short_fn; | ||
832 | const char *user; | ||
833 | GNUNET_HashCode hc; | ||
834 | |||
835 | GNUNET_CONTAINER_multihashmap_destroy (adc->metamap); | ||
836 | if (adc->parent_ctx) | ||
837 | adc->parent_ctx->dir_entry_count += 1; | ||
838 | short_fn = adc->parent_filename; | ||
839 | while ( (NULL != (ss = strstr (short_fn, DIR_SEPARATOR_STR))) && | ||
840 | (ss[1] != '\0') ) | ||
841 | short_fn = 1 + ss; | ||
842 | user = getenv ("USER"); | ||
843 | if ((user == NULL) || (0 != strncasecmp (user, short_fn, strlen(user)))) | ||
844 | { | ||
845 | /* only use filename if it doesn't match $USER */ | ||
846 | GNUNET_CONTAINER_meta_data_insert (adc->pd->meta, "<gnunet-gtk>", | ||
847 | EXTRACTOR_METATYPE_FILENAME, | ||
848 | EXTRACTOR_METAFORMAT_UTF8, | ||
849 | "text/plain", short_fn, | ||
850 | strlen (short_fn) + 1); | ||
851 | GNUNET_CONTAINER_meta_data_insert (adc->pd->meta, "<gnunet-gtk>", | ||
852 | EXTRACTOR_METATYPE_GNUNET_ORIGINAL_FILENAME, | ||
853 | EXTRACTOR_METAFORMAT_UTF8, | ||
854 | "text/plain", short_fn, | ||
855 | strlen (short_fn) + 1); | ||
856 | } | ||
857 | if (adc->parent_ctx != NULL) | ||
858 | { | ||
859 | if (adc->parent_ctx->metamap != NULL) | ||
860 | { | ||
861 | GNUNET_CRYPTO_hash (adc->parent_filename, strlen (adc->parent_filename), &hc); | ||
862 | GNUNET_CONTAINER_multihashmap_put (adc->parent_ctx->metamap, &hc, adc->pd, | ||
863 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY); | ||
864 | /* FIXME: what if this put fails? I think it actually can... Why unique only? */ | ||
865 | GNUNET_FS_uri_ksk_get_keywords (adc->pd->ksk_uri, &add_to_keyword_counter, adc->parent_ctx->keywordcounter); | ||
866 | } | ||
867 | else | ||
868 | { | ||
869 | GNUNET_assert (adc->parent_ctx->keywordcounter == NULL); | ||
870 | add_entry_to_ts (GTK_TREE_STORE (adc->ctx->file_info_treemodel), | ||
871 | &adc->pd->iter, adc->parent_filename, &adc->bo, adc->do_index, | ||
872 | adc->pd->ksk_uri, NULL, adc->pd->meta); | ||
873 | } | ||
874 | } | ||
875 | GNUNET_FS_uri_destroy (adc->exclude_ksk); | ||
876 | if (adc->parent_ctx != NULL) | ||
877 | add_dir_callback (adc->parent_ctx, adc->parent_iter, | ||
878 | adc->parent_filename, NULL); | ||
879 | GNUNET_free_non_null (adc->parent_filename); | ||
880 | GNUNET_free (adc); | ||
804 | } | 881 | } |
805 | 882 | ||
883 | static void | ||
884 | publish_dir_callback (void *cls, struct GNUNET_DISK_DirectoryIterator *di, | ||
885 | const char *filename, const char *dirname) | ||
886 | { | ||
887 | struct AddDirContext *adc = cls; | ||
888 | struct PublishData *pd; | ||
889 | GNUNET_HashCode hc; | ||
890 | struct stat sbuf; | ||
891 | |||
892 | GNUNET_CRYPTO_hash (filename, strlen (filename), &hc); | ||
893 | pd = GNUNET_CONTAINER_multihashmap_get (adc->metamap, &hc); | ||
894 | /* stat() is needed here to match the stat() call add_dir_callback() does */ | ||
895 | if ((pd != NULL) && (0 == STAT (filename, &sbuf))) | ||
896 | { | ||
897 | add_entry_to_ts (GTK_TREE_STORE (adc->ctx->file_info_treemodel), | ||
898 | &pd->iter, filename, &adc->bo, adc->do_index, | ||
899 | pd->ksk_uri, adc->exclude_ksk, pd->meta); | ||
900 | } | ||
901 | if (pd != NULL) | ||
902 | { | ||
903 | GNUNET_CONTAINER_multihashmap_remove (adc->metamap, &hc, pd); | ||
904 | GNUNET_free (pd); | ||
905 | } | ||
906 | if (GNUNET_DISK_directory_iterator_next (di, GNUNET_NO) != GNUNET_YES) | ||
907 | { | ||
908 | child_dir_finished_publishing (adc); | ||
909 | } | ||
910 | } | ||
911 | |||
912 | static void | ||
913 | child_dir_finished_scanning (struct AddDirContext *adc) | ||
914 | { | ||
915 | adc->pd->ksk_uri = process_keywords (adc); | ||
916 | adc->pd->meta = GNUNET_CONTAINER_meta_data_create (); | ||
917 | adc->exclude_ksk = GNUNET_FS_uri_dup (adc->pd->ksk_uri); | ||
918 | if (GNUNET_YES != GNUNET_DISK_directory_iterator_start (GNUNET_SCHEDULER_PRIORITY_IDLE, | ||
919 | adc->parent_filename, &publish_dir_callback, adc)) | ||
920 | child_dir_finished_publishing (adc); | ||
921 | } | ||
922 | |||
923 | /** | ||
924 | * Function called by directory iterator. | ||
925 | * | ||
926 | * @param cls closure | ||
927 | * @param di argument to pass to "GNUNET_DISK_directory_iterator_next" to | ||
928 | * get called on the next entry (or finish cleanly); | ||
929 | * NULL on error (will be the last call in that case) | ||
930 | * @param filename complete filename (absolute path) | ||
931 | * @param dirname directory name (absolute path) | ||
932 | */ | ||
933 | static void | ||
934 | add_dir_callback (void *cls, struct GNUNET_DISK_DirectoryIterator * di, | ||
935 | const char *filename, const char *dirname) | ||
936 | { | ||
937 | struct AddDirContext *adc = cls, *child_adc; | ||
938 | struct stat sbuf; | ||
939 | int will_continue; | ||
940 | |||
941 | /* dirname == NULL is a special case when add_dir_callback() is called by | ||
942 | * the child directory iterator callback. | ||
943 | */ | ||
944 | if (dirname == NULL) | ||
945 | { | ||
946 | if (di == NULL) | ||
947 | return; | ||
948 | else | ||
949 | will_continue = GNUNET_DISK_directory_iterator_next (di, GNUNET_NO); | ||
950 | } | ||
951 | else if (0 != STAT (filename, &sbuf)) | ||
952 | { | ||
953 | GNUNET_assert (di != NULL); | ||
954 | will_continue = GNUNET_DISK_directory_iterator_next (di, GNUNET_NO); | ||
955 | } | ||
956 | else | ||
957 | { | ||
958 | if (!S_ISDIR (sbuf.st_mode)) | ||
959 | { | ||
960 | GNUNET_assert (adc->metamap != NULL); | ||
961 | extract_file (adc, filename); | ||
962 | will_continue = GNUNET_DISK_directory_iterator_next (di, GNUNET_NO); | ||
963 | } | ||
964 | else | ||
965 | { | ||
966 | child_adc = GNUNET_malloc (sizeof (struct AddDirContext)); | ||
967 | will_continue = GNUNET_DISK_directory_iterator_start (GNUNET_SCHEDULER_PRIORITY_IDLE, | ||
968 | filename, &add_dir_callback, child_adc); | ||
969 | if (will_continue != GNUNET_YES) | ||
970 | { | ||
971 | /* Ignore empty directories for now */ | ||
972 | GNUNET_free (child_adc); | ||
973 | will_continue = GNUNET_DISK_directory_iterator_next (di, GNUNET_NO); | ||
974 | } | ||
975 | else | ||
976 | { | ||
977 | child_adc->metamap = GNUNET_CONTAINER_multihashmap_create (1024); | ||
978 | child_adc->keywordcounter = GNUNET_CONTAINER_multihashmap_create (1024); | ||
979 | child_adc->dir_entry_count = 0; | ||
980 | child_adc->parent_ctx = adc; | ||
981 | child_adc->parent_iter = di; | ||
982 | child_adc->bo = adc->bo; | ||
983 | child_adc->do_index = adc->do_index; | ||
984 | child_adc->ctx = adc->ctx; | ||
985 | child_adc->pd = GNUNET_malloc (sizeof (struct PublishData)); | ||
986 | child_adc->parent_filename = GNUNET_strdup (filename); | ||
987 | gtk_tree_store_insert_before (GTK_TREE_STORE (adc->ctx->file_info_treemodel), | ||
988 | &child_adc->pd->iter, adc->parent, NULL); | ||
989 | child_adc->parent = &child_adc->pd->iter; | ||
990 | /* Don't advance directory iterator here, child iterator will call | ||
991 | * us with dirname == NULL for that later. | ||
992 | */ | ||
993 | } | ||
994 | } | ||
995 | } | ||
996 | if (will_continue != GNUNET_YES) | ||
997 | { | ||
998 | child_dir_finished_scanning (adc); | ||
999 | } | ||
1000 | return; | ||
1001 | } | ||
1002 | |||
1003 | |||
806 | /** | 1004 | /** |
807 | * Add a directory to the tree model. | 1005 | * Add a directory to the tree model. |
808 | * | 1006 | * |
@@ -816,6 +1014,7 @@ add_dir (struct MainPublishingDialogContext *ctx, const char *filename, | |||
816 | { | 1014 | { |
817 | struct stat sbuf; | 1015 | struct stat sbuf; |
818 | struct AddDirContext *scan_ctx; | 1016 | struct AddDirContext *scan_ctx; |
1017 | char *filename_expanded; | ||
819 | 1018 | ||
820 | if (0 != STAT (filename, &sbuf)) | 1019 | if (0 != STAT (filename, &sbuf)) |
821 | return; | 1020 | return; |
@@ -824,12 +1023,17 @@ add_dir (struct MainPublishingDialogContext *ctx, const char *filename, | |||
824 | GNUNET_break (0); | 1023 | GNUNET_break (0); |
825 | return; | 1024 | return; |
826 | } | 1025 | } |
1026 | filename_expanded = GNUNET_STRINGS_filename_expand (filename); | ||
1027 | if (filename_expanded == NULL) | ||
1028 | return; | ||
827 | scan_ctx = GNUNET_malloc (sizeof (struct AddDirContext)); | 1029 | scan_ctx = GNUNET_malloc (sizeof (struct AddDirContext)); |
828 | scan_ctx->bo = *bo; | 1030 | scan_ctx->bo = *bo; |
829 | scan_ctx->do_index = do_index; | 1031 | scan_ctx->do_index = do_index; |
830 | scan_ctx->ctx = ctx; | 1032 | scan_ctx->ctx = ctx; |
831 | scan_directory (scan_ctx, filename); | 1033 | |
832 | add_dir_finish (scan_ctx); | 1034 | /* just make sure that dirname is not NULL, it's not really used */ |
1035 | add_dir_callback (scan_ctx, NULL, filename_expanded, filename_expanded); | ||
1036 | GNUNET_free (filename_expanded); | ||
833 | } | 1037 | } |
834 | 1038 | ||
835 | 1039 | ||
@@ -1198,15 +1402,21 @@ master_publish_edit_publish_dialog_cb (gpointer cls, int do_index, | |||
1198 | gint ret) | 1402 | gint ret) |
1199 | { | 1403 | { |
1200 | struct EditPublishContext *cbargs = cls; | 1404 | struct EditPublishContext *cbargs = cls; |
1405 | struct GNUNET_FileInformation *fi; | ||
1406 | const char *filename; | ||
1201 | 1407 | ||
1202 | GNUNET_assert (NULL == root); | 1408 | GNUNET_assert (NULL == root); |
1203 | if (ret == GTK_RESPONSE_OK) | 1409 | if (ret == GTK_RESPONSE_OK) |
1410 | { | ||
1204 | gtk_tree_store_set (GTK_TREE_STORE (cbargs->tm), &cbargs->iter, 1, do_index, | 1411 | gtk_tree_store_set (GTK_TREE_STORE (cbargs->tm), &cbargs->iter, 1, do_index, |
1205 | 2, short_fn, 3, (guint) bo->anonymity_level, 4, | 1412 | 2, short_fn, 3, (guint) bo->anonymity_level, 4, |
1206 | (guint) bo->content_priority, | 1413 | (guint) bo->content_priority, |
1207 | 6, (guint64) bo->expiration_time.abs_value, | 1414 | 6, (guint64) bo->expiration_time.abs_value, |
1208 | 7, (guint) bo->replication_level, | 1415 | 7, (guint) bo->replication_level, |
1209 | -1); | 1416 | -1); |
1417 | gtk_tree_model_get (cbargs->tm, &cbargs->iter, 5, &fi); | ||
1418 | GNUNET_FS_file_information_set_filename (fi, short_fn); | ||
1419 | } | ||
1210 | GNUNET_free (cbargs); | 1420 | GNUNET_free (cbargs); |
1211 | } | 1421 | } |
1212 | 1422 | ||