aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2012-01-09 16:46:39 +0000
committerChristian Grothoff <christian@grothoff.org>2012-01-09 16:46:39 +0000
commit474f9794b40f029e45e61cbfa2dd8a781a811ae1 (patch)
treeee7878cb19e13f87b8a1c9000a6ae65be040cb75
parent0b2c209a381b00fcd8ac982b4ea0899411deaf8b (diff)
downloadgnunet-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.c16
-rw-r--r--src/fs/gnunet-fs-gtk-main_window_adv_pseudonym.c2
-rw-r--r--src/fs/gnunet-fs-gtk-main_window_file_publish.c222
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
822static void
823add_dir_callback (void *cls, struct GNUNET_DISK_DirectoryIterator * di,
824 const char *filename, const char *dirname);
825
799 826
800static void 827static void
801add_dir_finish (struct AddDirContext *scan_ctx) 828child_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
883static void
884publish_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
912static void
913child_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 */
933static void
934add_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