aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/fs/fs.c173
-rw-r--r--src/fs/fs.h38
-rw-r--r--src/fs/fs_search.c81
-rw-r--r--src/include/gnunet_fs_service.h10
4 files changed, 147 insertions, 155 deletions
diff --git a/src/fs/fs.c b/src/fs/fs.c
index f69fd564d..15fe86f71 100644
--- a/src/fs/fs.c
+++ b/src/fs/fs.c
@@ -1706,14 +1706,14 @@ GNUNET_FS_search_result_sync_ (struct GNUNET_FS_SearchResult *sr)
1706 uris = NULL; 1706 uris = NULL;
1707 if (NULL == sr->serialization) 1707 if (NULL == sr->serialization)
1708 sr->serialization = make_serialization_file_name_in_dir (sr->sc->h, 1708 sr->serialization = make_serialization_file_name_in_dir (sr->sc->h,
1709 (sr->sc->parent == NULL) 1709 (sr->sc->psearch_result == NULL)
1710 ? GNUNET_FS_SYNC_PATH_MASTER_SEARCH 1710 ? GNUNET_FS_SYNC_PATH_MASTER_SEARCH
1711 : GNUNET_FS_SYNC_PATH_CHILD_SEARCH, 1711 : GNUNET_FS_SYNC_PATH_CHILD_SEARCH,
1712 sr->sc->serialization); 1712 sr->sc->serialization);
1713 if (NULL == sr->serialization) 1713 if (NULL == sr->serialization)
1714 return; 1714 return;
1715 wh = get_write_handle_in_dir (sr->sc->h, 1715 wh = get_write_handle_in_dir (sr->sc->h,
1716 (sr->sc->parent == NULL) 1716 (sr->sc->psearch_result == NULL)
1717 ? GNUNET_FS_SYNC_PATH_MASTER_SEARCH 1717 ? GNUNET_FS_SYNC_PATH_MASTER_SEARCH
1718 : GNUNET_FS_SYNC_PATH_CHILD_SEARCH, 1718 : GNUNET_FS_SYNC_PATH_CHILD_SEARCH,
1719 sr->sc->serialization, 1719 sr->sc->serialization,
@@ -1724,6 +1724,8 @@ GNUNET_FS_search_result_sync_ (struct GNUNET_FS_SearchResult *sr)
1724 (GNUNET_OK != 1724 (GNUNET_OK !=
1725 GNUNET_BIO_write_string (wh, sr->download != NULL ? sr->download->serialization : NULL)) || 1725 GNUNET_BIO_write_string (wh, sr->download != NULL ? sr->download->serialization : NULL)) ||
1726 (GNUNET_OK != 1726 (GNUNET_OK !=
1727 GNUNET_BIO_write_string (wh, sr->update_search != NULL ? sr->update_search->serialization : NULL)) ||
1728 (GNUNET_OK !=
1727 GNUNET_BIO_write_meta_data (wh, sr->meta)) || 1729 GNUNET_BIO_write_meta_data (wh, sr->meta)) ||
1728 (GNUNET_OK != 1730 (GNUNET_OK !=
1729 GNUNET_BIO_write (wh, &sr->key, sizeof (GNUNET_HashCode))) || 1731 GNUNET_BIO_write (wh, &sr->key, sizeof (GNUNET_HashCode))) ||
@@ -1749,7 +1751,7 @@ GNUNET_FS_search_result_sync_ (struct GNUNET_FS_SearchResult *sr)
1749 if (wh != NULL) 1751 if (wh != NULL)
1750 (void) GNUNET_BIO_write_close (wh); 1752 (void) GNUNET_BIO_write_close (wh);
1751 remove_sync_file_in_dir (sr->sc->h, 1753 remove_sync_file_in_dir (sr->sc->h,
1752 (sr->sc->parent == NULL) 1754 (sr->sc->psearch_result == NULL)
1753 ? GNUNET_FS_SYNC_PATH_MASTER_SEARCH 1755 ? GNUNET_FS_SYNC_PATH_MASTER_SEARCH
1754 : GNUNET_FS_SYNC_PATH_CHILD_SEARCH, 1756 : GNUNET_FS_SYNC_PATH_CHILD_SEARCH,
1755 sr->sc->serialization, 1757 sr->sc->serialization,
@@ -1771,13 +1773,13 @@ void
1771GNUNET_FS_search_sync_ (struct GNUNET_FS_SearchContext *sc) 1773GNUNET_FS_search_sync_ (struct GNUNET_FS_SearchContext *sc)
1772{ 1774{
1773 struct GNUNET_BIO_WriteHandle *wh; 1775 struct GNUNET_BIO_WriteHandle *wh;
1774 struct GNUNET_FS_SearchContext *scc;
1775 char *uris; 1776 char *uris;
1776 char in_pause; 1777 char in_pause;
1777 const char *category; 1778 const char *category;
1778
1779 1779
1780 category = (sc->parent == NULL) ? GNUNET_FS_SYNC_PATH_MASTER_SEARCH : GNUNET_FS_SYNC_PATH_CHILD_SEARCH; 1780 category = (sc->psearch_result == NULL)
1781 ? GNUNET_FS_SYNC_PATH_MASTER_SEARCH
1782 : GNUNET_FS_SYNC_PATH_CHILD_SEARCH;
1781 if (NULL == sc->serialization) 1783 if (NULL == sc->serialization)
1782 sc->serialization = make_serialization_file_name (sc->h, 1784 sc->serialization = make_serialization_file_name (sc->h,
1783 category); 1785 category);
@@ -1803,17 +1805,6 @@ GNUNET_FS_search_sync_ (struct GNUNET_FS_SearchContext *sc)
1803 goto cleanup; 1805 goto cleanup;
1804 GNUNET_free (uris); 1806 GNUNET_free (uris);
1805 uris = NULL; 1807 uris = NULL;
1806 scc = sc->child_head;
1807 while (NULL != scc)
1808 {
1809 if (scc->serialization == NULL)
1810 break;
1811 if (GNUNET_OK !=
1812 GNUNET_BIO_write_string (wh, scc->serialization))
1813 goto cleanup;
1814 scc = scc->next;
1815 }
1816 GNUNET_BIO_write_string (wh, NULL);
1817 if (GNUNET_OK != 1808 if (GNUNET_OK !=
1818 GNUNET_BIO_write_close (wh)) 1809 GNUNET_BIO_write_close (wh))
1819 { 1810 {
@@ -1971,6 +1962,21 @@ deserialize_download (struct GNUNET_FS_Handle *h,
1971 1962
1972 1963
1973/** 1964/**
1965 * Deserialize a search.
1966 *
1967 * @param h overall context
1968 * @param rh file to deserialize from
1969 * @param psearch_result parent search result
1970 * @param serialization name under which the search was serialized
1971 */
1972static struct GNUNET_FS_SearchContext *
1973deserialize_search (struct GNUNET_FS_Handle *h,
1974 struct GNUNET_BIO_ReadHandle *rh,
1975 struct GNUNET_FS_SearchResult *psearch_result,
1976 const char *serialization);
1977
1978
1979/**
1974 * Function called with a filename of serialized search result 1980 * Function called with a filename of serialized search result
1975 * to deserialize. 1981 * to deserialize.
1976 * 1982 *
@@ -1987,6 +1993,7 @@ deserialize_search_result (void *cls,
1987 char *uris; 1993 char *uris;
1988 char *emsg; 1994 char *emsg;
1989 char *download; 1995 char *download;
1996 char *update_srch;
1990 struct GNUNET_BIO_ReadHandle *rh; 1997 struct GNUNET_BIO_ReadHandle *rh;
1991 struct GNUNET_BIO_ReadHandle *drh; 1998 struct GNUNET_BIO_ReadHandle *drh;
1992 struct GNUNET_FS_SearchResult *sr; 1999 struct GNUNET_FS_SearchResult *sr;
@@ -1998,7 +2005,7 @@ deserialize_search_result (void *cls,
1998 if (ser != NULL) 2005 if (ser != NULL)
1999 { 2006 {
2000 remove_sync_file_in_dir (sc->h, 2007 remove_sync_file_in_dir (sc->h,
2001 (sc->parent == NULL) 2008 (sc->psearch_result == NULL)
2002 ? GNUNET_FS_SYNC_PATH_MASTER_SEARCH 2009 ? GNUNET_FS_SYNC_PATH_MASTER_SEARCH
2003 : GNUNET_FS_SYNC_PATH_CHILD_SEARCH, 2010 : GNUNET_FS_SYNC_PATH_CHILD_SEARCH,
2004 sc->serialization, 2011 sc->serialization,
@@ -2018,6 +2025,8 @@ deserialize_search_result (void *cls,
2018 (GNUNET_OK != 2025 (GNUNET_OK !=
2019 GNUNET_BIO_read_string (rh, "download-lnk", &download, 16)) || 2026 GNUNET_BIO_read_string (rh, "download-lnk", &download, 16)) ||
2020 (GNUNET_OK != 2027 (GNUNET_OK !=
2028 GNUNET_BIO_read_string (rh, "search-lnk", &update_srch, 16)) ||
2029 (GNUNET_OK !=
2021 GNUNET_BIO_read_meta_data (rh, "result-meta", &sr->meta)) || 2030 GNUNET_BIO_read_meta_data (rh, "result-meta", &sr->meta)) ||
2022 (GNUNET_OK != 2031 (GNUNET_OK !=
2023 GNUNET_BIO_read (rh, "result-key", &sr->key, sizeof (GNUNET_HashCode))) || 2032 GNUNET_BIO_read (rh, "result-key", &sr->key, sizeof (GNUNET_HashCode))) ||
@@ -2052,6 +2061,26 @@ deserialize_search_result (void *cls,
2052 } 2061 }
2053 GNUNET_free (download); 2062 GNUNET_free (download);
2054 } 2063 }
2064 if (update_srch != NULL)
2065 {
2066 drh = get_read_handle (sc->h,
2067 GNUNET_FS_SYNC_PATH_CHILD_SEARCH,
2068 update_srch);
2069 deserialize_search (sc->h,
2070 drh,
2071 sr,
2072 update_srch);
2073 if (GNUNET_OK !=
2074 GNUNET_BIO_read_close (drh, &emsg))
2075 {
2076 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
2077 _("Failed to resume sub-search `%s': %s\n"),
2078 update_srch,
2079 emsg);
2080 GNUNET_free (emsg);
2081 }
2082 GNUNET_free (update_srch);
2083 }
2055 GNUNET_CONTAINER_multihashmap_put (sc->master_result_map, 2084 GNUNET_CONTAINER_multihashmap_put (sc->master_result_map,
2056 &sr->key, 2085 &sr->key,
2057 sr, 2086 sr,
@@ -2102,6 +2131,16 @@ signal_download_resume (struct GNUNET_FS_DownloadContext *dc)
2102 2131
2103 2132
2104/** 2133/**
2134 * Signal resuming of a search to our clients (for the
2135 * top level search and all sub-searches).
2136 *
2137 * @param sc search being resumed
2138 */
2139static void
2140signal_search_resume (struct GNUNET_FS_SearchContext *sc);
2141
2142
2143/**
2105 * Iterator over search results signaling resume to the client for 2144 * Iterator over search results signaling resume to the client for
2106 * each result. 2145 * each result.
2107 * 2146 *
@@ -2139,11 +2178,22 @@ signal_result_resume (void *cls,
2139 { 2178 {
2140 GNUNET_FS_search_start_probe_ (sr); 2179 GNUNET_FS_search_start_probe_ (sr);
2141 } 2180 }
2181 if (sr->update_search != NULL)
2182 signal_search_resume (sr->update_search);
2142 return GNUNET_YES; 2183 return GNUNET_YES;
2143} 2184}
2144 2185
2145 2186
2146/** 2187/**
2188 * Free memory allocated by the search context and its children
2189 *
2190 * @param sc search context to free
2191 */
2192static void
2193free_search_context (struct GNUNET_FS_SearchContext *sc);
2194
2195
2196/**
2147 * Iterator over search results freeing each. 2197 * Iterator over search results freeing each.
2148 * 2198 *
2149 * @param cls closure, the 'struct GNUNET_FS_SearchContext' 2199 * @param cls closure, the 'struct GNUNET_FS_SearchContext'
@@ -2158,6 +2208,11 @@ free_result (void *cls,
2158{ 2208{
2159 struct GNUNET_FS_SearchResult *sr = value; 2209 struct GNUNET_FS_SearchResult *sr = value;
2160 2210
2211 if (sr->update_search != NULL)
2212 {
2213 free_search_context (sr->update_search);
2214 GNUNET_assert (NULL == sr->update_search);
2215 }
2161 GNUNET_CONTAINER_meta_data_destroy (sr->meta); 2216 GNUNET_CONTAINER_meta_data_destroy (sr->meta);
2162 GNUNET_FS_uri_destroy (sr->uri); 2217 GNUNET_FS_uri_destroy (sr->uri);
2163 GNUNET_free (sr); 2218 GNUNET_free (sr);
@@ -2173,30 +2228,21 @@ free_result (void *cls,
2173static void 2228static void
2174free_search_context (struct GNUNET_FS_SearchContext *sc) 2229free_search_context (struct GNUNET_FS_SearchContext *sc)
2175{ 2230{
2176 struct GNUNET_FS_SearchContext *scc;
2177
2178 while (NULL != (scc = sc->child_head))
2179 {
2180 GNUNET_CONTAINER_DLL_remove (sc->child_head,
2181 sc->child_tail,
2182 scc);
2183 free_search_context (scc);
2184 }
2185 GNUNET_free_non_null (sc->emsg);
2186 if (sc->serialization != NULL) 2231 if (sc->serialization != NULL)
2187 { 2232 {
2188 GNUNET_FS_remove_sync_file_ (sc->h, 2233 GNUNET_FS_remove_sync_file_ (sc->h,
2189 (sc->parent == NULL) 2234 (sc->psearch_result == NULL)
2190 ? GNUNET_FS_SYNC_PATH_MASTER_SEARCH 2235 ? GNUNET_FS_SYNC_PATH_MASTER_SEARCH
2191 : GNUNET_FS_SYNC_PATH_CHILD_SEARCH, 2236 : GNUNET_FS_SYNC_PATH_CHILD_SEARCH,
2192 sc->serialization); 2237 sc->serialization);
2193 GNUNET_FS_remove_sync_dir_ (sc->h, 2238 GNUNET_FS_remove_sync_dir_ (sc->h,
2194 (sc->parent == NULL) 2239 (sc->psearch_result == NULL)
2195 ? GNUNET_FS_SYNC_PATH_MASTER_SEARCH 2240 ? GNUNET_FS_SYNC_PATH_MASTER_SEARCH
2196 : GNUNET_FS_SYNC_PATH_CHILD_SEARCH, 2241 : GNUNET_FS_SYNC_PATH_CHILD_SEARCH,
2197 sc->serialization); 2242 sc->serialization);
2198 } 2243 }
2199 GNUNET_free_non_null (sc->serialization); 2244 GNUNET_free_non_null (sc->serialization);
2245 GNUNET_free_non_null (sc->emsg);
2200 if (sc->uri != NULL) 2246 if (sc->uri != NULL)
2201 GNUNET_FS_uri_destroy (sc->uri); 2247 GNUNET_FS_uri_destroy (sc->uri);
2202 if (sc->master_result_map != NULL) 2248 if (sc->master_result_map != NULL)
@@ -2407,7 +2453,6 @@ deserialize_download (struct GNUNET_FS_Handle *h,
2407static void 2453static void
2408signal_search_resume (struct GNUNET_FS_SearchContext *sc) 2454signal_search_resume (struct GNUNET_FS_SearchContext *sc)
2409{ 2455{
2410 struct GNUNET_FS_SearchContext *scc;
2411 struct GNUNET_FS_ProgressInfo pi; 2456 struct GNUNET_FS_ProgressInfo pi;
2412 2457
2413 pi.status = GNUNET_FS_STATUS_SEARCH_RESUME; 2458 pi.status = GNUNET_FS_STATUS_SEARCH_RESUME;
@@ -2415,12 +2460,10 @@ signal_search_resume (struct GNUNET_FS_SearchContext *sc)
2415 pi.value.search.specifics.resume.is_paused = (sc->client == NULL) ? GNUNET_YES : GNUNET_NO; 2460 pi.value.search.specifics.resume.is_paused = (sc->client == NULL) ? GNUNET_YES : GNUNET_NO;
2416 sc->client_info = GNUNET_FS_search_make_status_ (&pi, 2461 sc->client_info = GNUNET_FS_search_make_status_ (&pi,
2417 sc); 2462 sc);
2418 scc = sc->child_head; 2463 GNUNET_CONTAINER_multihashmap_iterate (sc->master_result_map,
2419 while (NULL != scc) 2464 &signal_result_resume,
2420 { 2465 sc);
2421 signal_search_resume (scc); 2466
2422 scc = scc->next;
2423 }
2424} 2467}
2425 2468
2426 2469
@@ -2429,29 +2472,36 @@ signal_search_resume (struct GNUNET_FS_SearchContext *sc)
2429 * 2472 *
2430 * @param h overall context 2473 * @param h overall context
2431 * @param rh file to deserialize from 2474 * @param rh file to deserialize from
2432 * @param parent parent search 2475 * @param psearch_result parent search result
2433 * @param serialization name under which the search was serialized 2476 * @param serialization name under which the search was serialized
2434 */ 2477 */
2435static struct GNUNET_FS_SearchContext * 2478static struct GNUNET_FS_SearchContext *
2436deserialize_search (struct GNUNET_FS_Handle *h, 2479deserialize_search (struct GNUNET_FS_Handle *h,
2437 struct GNUNET_BIO_ReadHandle *rh, 2480 struct GNUNET_BIO_ReadHandle *rh,
2438 struct GNUNET_FS_SearchContext *parent, 2481 struct GNUNET_FS_SearchResult *psearch_result,
2439 const char *serialization) 2482 const char *serialization)
2440{ 2483{
2441 struct GNUNET_FS_SearchContext *sc; 2484 struct GNUNET_FS_SearchContext *sc;
2442 struct GNUNET_FS_SearchContext *scc;
2443 struct GNUNET_BIO_ReadHandle *rhc;
2444 char *emsg; 2485 char *emsg;
2445 char *uris; 2486 char *uris;
2446 char *child_ser;
2447 char *dn; 2487 char *dn;
2448 uint32_t options; 2488 uint32_t options;
2449 char in_pause; 2489 char in_pause;
2450 2490
2491 if ( (psearch_result != NULL) &&
2492 (psearch_result->update_search != NULL) )
2493 {
2494 GNUNET_break (0);
2495 return NULL;
2496 }
2451 uris = NULL; 2497 uris = NULL;
2452 emsg = NULL; 2498 emsg = NULL;
2453 sc = GNUNET_malloc (sizeof (struct GNUNET_FS_SearchContext)); 2499 sc = GNUNET_malloc (sizeof (struct GNUNET_FS_SearchContext));
2454 sc->parent = parent; 2500 if (psearch_result != NULL)
2501 {
2502 sc->psearch_result = psearch_result;
2503 psearch_result->update_search = sc;
2504 }
2455 sc->h = h; 2505 sc->h = h;
2456 sc->serialization = GNUNET_strdup (serialization); 2506 sc->serialization = GNUNET_strdup (serialization);
2457 if ( (GNUNET_OK != 2507 if ( (GNUNET_OK !=
@@ -2473,7 +2523,7 @@ deserialize_search (struct GNUNET_FS_Handle *h,
2473 sc->options = (enum GNUNET_FS_SearchOptions) options; 2523 sc->options = (enum GNUNET_FS_SearchOptions) options;
2474 sc->master_result_map = GNUNET_CONTAINER_multihashmap_create (16); 2524 sc->master_result_map = GNUNET_CONTAINER_multihashmap_create (16);
2475 dn = get_serialization_file_name_in_dir (h, 2525 dn = get_serialization_file_name_in_dir (h,
2476 (sc->parent == NULL) 2526 (sc->psearch_result == NULL)
2477 ? GNUNET_FS_SYNC_PATH_MASTER_SEARCH 2527 ? GNUNET_FS_SYNC_PATH_MASTER_SEARCH
2478 : GNUNET_FS_SYNC_PATH_CHILD_SEARCH, 2528 : GNUNET_FS_SYNC_PATH_CHILD_SEARCH,
2479 sc->serialization, 2529 sc->serialization,
@@ -2490,42 +2540,7 @@ deserialize_search (struct GNUNET_FS_Handle *h,
2490 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, 2540 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
2491 _("Could not resume running search, will resume as paused search\n")); 2541 _("Could not resume running search, will resume as paused search\n"));
2492 } 2542 }
2493 while (1)
2494 {
2495 if ( (GNUNET_OK !=
2496 GNUNET_BIO_read_string (rh, "child-serialization", &child_ser, 32)))
2497 goto cleanup;
2498 if (child_ser == NULL)
2499 break;
2500 rhc = get_read_handle (h, GNUNET_FS_SYNC_PATH_CHILD_SEARCH, child_ser);
2501 if (rhc != NULL)
2502 {
2503 scc = deserialize_search (h, rhc, sc, child_ser);
2504 if (scc != NULL)
2505 GNUNET_CONTAINER_DLL_insert (sc->child_head,
2506 sc->child_tail,
2507 scc);
2508 emsg = NULL;
2509 if (GNUNET_OK !=
2510 GNUNET_BIO_read_close (rhc, &emsg))
2511 {
2512 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
2513 _("Failed to resume sub-search `%s': %s\n"),
2514 child_ser,
2515 emsg);
2516 GNUNET_free (emsg);
2517 }
2518 }
2519 GNUNET_free (child_ser);
2520 }
2521 if (parent != NULL)
2522 GNUNET_CONTAINER_DLL_insert (parent->child_head,
2523 parent->child_tail,
2524 sc);
2525 signal_search_resume (sc); 2543 signal_search_resume (sc);
2526 GNUNET_CONTAINER_multihashmap_iterate (sc->master_result_map,
2527 &signal_result_resume,
2528 sc);
2529 GNUNET_free (uris); 2544 GNUNET_free (uris);
2530 return sc; 2545 return sc;
2531 cleanup: 2546 cleanup:
diff --git a/src/fs/fs.h b/src/fs/fs.h
index f4f21faea..d7dcd987d 100644
--- a/src/fs/fs.h
+++ b/src/fs/fs.h
@@ -646,12 +646,16 @@ struct GNUNET_FS_SearchResult
646 /** 646 /**
647 * ID of an associated download based on this search result (or 647 * ID of an associated download based on this search result (or
648 * NULL for none). 648 * NULL for none).
649 *
650 * FIXME: not yet serialized.
651 */ 649 */
652 struct GNUNET_FS_DownloadContext *download; 650 struct GNUNET_FS_DownloadContext *download;
653 651
654 /** 652 /**
653 * If this search result triggered an update search, this field
654 * links to the update search.
655 */
656 struct GNUNET_FS_SearchContext *update_search;
657
658 /**
655 * Name under which this search result is stored on disk. 659 * Name under which this search result is stored on disk.
656 */ 660 */
657 char *serialization; 661 char *serialization;
@@ -1457,34 +1461,10 @@ struct GNUNET_FS_SearchContext
1457 struct GNUNET_FS_Uri *uri; 1461 struct GNUNET_FS_Uri *uri;
1458 1462
1459 /** 1463 /**
1460 * For update-searches, link to the base-SKS search that triggered 1464 * For update-searches, link to the search result that triggered
1461 * the update search; otherwise NULL.
1462 */
1463 struct GNUNET_FS_SearchContext *parent;
1464
1465 /**
1466 * For update-searches, link to the first child search that
1467 * triggered the update search; otherwise NULL.
1468 */
1469 struct GNUNET_FS_SearchContext *child_head;
1470
1471 /**
1472 * For update-searches, link to the last child search that triggered
1473 * the update search; otherwise NULL. 1465 * the update search; otherwise NULL.
1474 */ 1466 */
1475 struct GNUNET_FS_SearchContext *child_tail; 1467 struct GNUNET_FS_SearchResult *psearch_result;
1476
1477 /**
1478 * For update-searches, link to the next child belonging to the same
1479 * parent.
1480 */
1481 struct GNUNET_FS_SearchContext *next;
1482
1483 /**
1484 * For update-searches, link to the previous child belonging to the
1485 * same parent.
1486 */
1487 struct GNUNET_FS_SearchContext *prev;
1488 1468
1489 /** 1469 /**
1490 * Connection to the FS service. 1470 * Connection to the FS service.
@@ -1618,8 +1598,6 @@ struct GNUNET_FS_DownloadContext
1618 /** 1598 /**
1619 * Associated search (used when downloading files 1599 * Associated search (used when downloading files
1620 * based on search results), or NULL for none. 1600 * based on search results), or NULL for none.
1621 *
1622 * FIXME: not yet serialized
1623 */ 1601 */
1624 struct GNUNET_FS_SearchResult *search; 1602 struct GNUNET_FS_SearchResult *search;
1625 1603
diff --git a/src/fs/fs_search.c b/src/fs/fs_search.c
index 8c324252f..9f62e04b1 100644
--- a/src/fs/fs_search.c
+++ b/src/fs/fs_search.c
@@ -53,7 +53,7 @@ GNUNET_FS_search_make_status_ (struct GNUNET_FS_ProgressInfo *pi,
53 pi->value.search.cctx 53 pi->value.search.cctx
54 = sc->client_info; 54 = sc->client_info;
55 pi->value.search.pctx 55 pi->value.search.pctx
56 = (sc->parent == NULL) ? NULL : sc->parent->client_info; 56 = (sc->psearch_result == NULL) ? NULL : sc->psearch_result->client_info;
57 pi->value.search.query 57 pi->value.search.query
58 = sc->uri; 58 = sc->uri;
59 pi->value.search.duration = GNUNET_TIME_absolute_get_duration (sc->start_time); 59 pi->value.search.duration = GNUNET_TIME_absolute_get_duration (sc->start_time);
@@ -462,7 +462,7 @@ process_ksk_result (struct GNUNET_FS_SearchContext *sc,
462 * @param anonymity desired level of anonymity 462 * @param anonymity desired level of anonymity
463 * @param options options for the search 463 * @param options options for the search
464 * @param cctx client context 464 * @param cctx client context
465 * @param parent parent search (for namespace update searches) 465 * @param psearch parent search result (for namespace update searches)
466 * @return context that can be used to control the search 466 * @return context that can be used to control the search
467 */ 467 */
468static struct GNUNET_FS_SearchContext * 468static struct GNUNET_FS_SearchContext *
@@ -471,7 +471,7 @@ search_start (struct GNUNET_FS_Handle *h,
471 uint32_t anonymity, 471 uint32_t anonymity,
472 enum GNUNET_FS_SearchOptions options, 472 enum GNUNET_FS_SearchOptions options,
473 void *cctx, 473 void *cctx,
474 struct GNUNET_FS_SearchContext *parent); 474 struct GNUNET_FS_SearchResult *psearch);
475 475
476 476
477/** 477/**
@@ -523,14 +523,12 @@ process_sks_result (struct GNUNET_FS_SearchContext *sc,
523 uu.type = sks; 523 uu.type = sks;
524 uu.data.sks.namespace = sc->uri->data.sks.namespace; 524 uu.data.sks.namespace = sc->uri->data.sks.namespace;
525 uu.data.sks.identifier = GNUNET_strdup (id_update); 525 uu.data.sks.identifier = GNUNET_strdup (id_update);
526 /* FIXME: should attach update search to the individual result, not 526 (void) search_start (sc->h,
527 the entire SKS search! */ 527 &uu,
528 search_start (sc->h, 528 sc->anonymity,
529 &uu, 529 sc->options,
530 sc->anonymity, 530 NULL,
531 sc->options, 531 sr);
532 NULL,
533 sc);
534} 532}
535 533
536 534
@@ -1064,7 +1062,7 @@ try_reconnect (struct GNUNET_FS_SearchContext *sc)
1064 * @param anonymity desired level of anonymity 1062 * @param anonymity desired level of anonymity
1065 * @param options options for the search 1063 * @param options options for the search
1066 * @param cctx initial value for the client context 1064 * @param cctx initial value for the client context
1067 * @param parent parent search (for namespace update searches) 1065 * @param psearch parent search result (for namespace update searches)
1068 * @return context that can be used to control the search 1066 * @return context that can be used to control the search
1069 */ 1067 */
1070static struct GNUNET_FS_SearchContext * 1068static struct GNUNET_FS_SearchContext *
@@ -1073,7 +1071,7 @@ search_start (struct GNUNET_FS_Handle *h,
1073 uint32_t anonymity, 1071 uint32_t anonymity,
1074 enum GNUNET_FS_SearchOptions options, 1072 enum GNUNET_FS_SearchOptions options,
1075 void *cctx, 1073 void *cctx,
1076 struct GNUNET_FS_SearchContext *parent) 1074 struct GNUNET_FS_SearchResult *psearch)
1077{ 1075{
1078 struct GNUNET_FS_SearchContext *sc; 1076 struct GNUNET_FS_SearchContext *sc;
1079 struct GNUNET_FS_ProgressInfo pi; 1077 struct GNUNET_FS_ProgressInfo pi;
@@ -1084,13 +1082,13 @@ search_start (struct GNUNET_FS_Handle *h,
1084 sc->uri = GNUNET_FS_uri_dup (uri); 1082 sc->uri = GNUNET_FS_uri_dup (uri);
1085 sc->anonymity = anonymity; 1083 sc->anonymity = anonymity;
1086 sc->start_time = GNUNET_TIME_absolute_get (); 1084 sc->start_time = GNUNET_TIME_absolute_get ();
1087 sc->parent = parent; 1085 if (psearch != NULL)
1086 {
1087 sc->psearch_result = psearch;
1088 psearch->update_search = sc;
1089 }
1088 sc->master_result_map = GNUNET_CONTAINER_multihashmap_create (16); 1090 sc->master_result_map = GNUNET_CONTAINER_multihashmap_create (16);
1089 sc->client_info = cctx; 1091 sc->client_info = cctx;
1090 if (NULL != parent)
1091 GNUNET_CONTAINER_DLL_insert (parent->child_head,
1092 parent->child_tail,
1093 sc);
1094 if (GNUNET_OK != 1092 if (GNUNET_OK !=
1095 GNUNET_FS_search_start_searching_ (sc)) 1093 GNUNET_FS_search_start_searching_ (sc))
1096 { 1094 {
@@ -1206,6 +1204,8 @@ search_result_freeze_probes (void *cls,
1206 sr->probe_cancel_task); 1204 sr->probe_cancel_task);
1207 sr->probe_cancel_task = GNUNET_SCHEDULER_NO_TASK; 1205 sr->probe_cancel_task = GNUNET_SCHEDULER_NO_TASK;
1208 } 1206 }
1207 if (sr->update_search != NULL)
1208 GNUNET_FS_search_pause (sr->update_search);
1209 return GNUNET_OK; 1209 return GNUNET_OK;
1210} 1210}
1211 1211
@@ -1226,11 +1226,23 @@ search_result_resume_probes (void *cls,
1226 struct GNUNET_FS_SearchResult *sr = value; 1226 struct GNUNET_FS_SearchResult *sr = value;
1227 1227
1228 GNUNET_FS_search_start_probe_ (sr); 1228 GNUNET_FS_search_start_probe_ (sr);
1229 if (sr->update_search != NULL)
1230 GNUNET_FS_search_continue (sr->update_search);
1229 return GNUNET_OK; 1231 return GNUNET_OK;
1230} 1232}
1231 1233
1232 1234
1233/** 1235/**
1236 * Create SUSPEND event for the given search operation
1237 * and then clean up our state (without stop signal).
1238 *
1239 * @param cls the 'struct GNUNET_FS_SearchContext' to signal for
1240 */
1241static void
1242search_signal_suspend (void *cls);
1243
1244
1245/**
1234 * Signal suspend and free the given search result. 1246 * Signal suspend and free the given search result.
1235 * 1247 *
1236 * @param cls the global FS handle 1248 * @param cls the global FS handle
@@ -1250,6 +1262,8 @@ search_result_suspend (void *cls,
1250 1262
1251 if (sr->download != NULL) 1263 if (sr->download != NULL)
1252 GNUNET_FS_download_signal_suspend_ (sr->download); 1264 GNUNET_FS_download_signal_suspend_ (sr->download);
1265 if (sr->update_search != NULL)
1266 search_signal_suspend (sr->update_search);
1253 pi.status = GNUNET_FS_STATUS_SEARCH_RESULT_SUSPEND; 1267 pi.status = GNUNET_FS_STATUS_SEARCH_RESULT_SUSPEND;
1254 pi.value.search.specifics.result_suspend.cctx = sr->client_info; 1268 pi.value.search.specifics.result_suspend.cctx = sr->client_info;
1255 pi.value.search.specifics.result_suspend.meta = sr->meta; 1269 pi.value.search.specifics.result_suspend.meta = sr->meta;
@@ -1279,20 +1293,10 @@ static void
1279search_signal_suspend (void *cls) 1293search_signal_suspend (void *cls)
1280{ 1294{
1281 struct GNUNET_FS_SearchContext *sc = cls; 1295 struct GNUNET_FS_SearchContext *sc = cls;
1282 struct GNUNET_FS_SearchContext *parent = cls;
1283 struct GNUNET_FS_ProgressInfo pi; 1296 struct GNUNET_FS_ProgressInfo pi;
1284 unsigned int i; 1297 unsigned int i;
1285 1298
1286 GNUNET_FS_end_top (sc->h, sc->top); 1299 GNUNET_FS_end_top (sc->h, sc->top);
1287 if (NULL != (parent = sc->parent))
1288 {
1289 GNUNET_CONTAINER_DLL_remove (parent->child_head,
1290 parent->child_tail,
1291 sc);
1292 sc->parent = NULL;
1293 }
1294 while (NULL != sc->child_head)
1295 search_signal_suspend (sc->child_head);
1296 GNUNET_CONTAINER_multihashmap_iterate (sc->master_result_map, 1300 GNUNET_CONTAINER_multihashmap_iterate (sc->master_result_map,
1297 &search_result_suspend, 1301 &search_result_suspend,
1298 sc); 1302 sc);
@@ -1426,6 +1430,11 @@ search_result_free (void *cls,
1426 GNUNET_FS_download_sync_ (sr->download); 1430 GNUNET_FS_download_sync_ (sr->download);
1427 sr->download = NULL; 1431 sr->download = NULL;
1428 } 1432 }
1433 if (NULL != sr->update_search)
1434 {
1435 GNUNET_FS_search_stop (sr->update_search);
1436 GNUNET_assert (sr->update_search == NULL);
1437 }
1429 pi.status = GNUNET_FS_STATUS_SEARCH_RESULT_STOPPED; 1438 pi.status = GNUNET_FS_STATUS_SEARCH_RESULT_STOPPED;
1430 pi.value.search.specifics.result_stopped.cctx = sr->client_info; 1439 pi.value.search.specifics.result_stopped.cctx = sr->client_info;
1431 pi.value.search.specifics.result_stopped.meta = sr->meta; 1440 pi.value.search.specifics.result_stopped.meta = sr->meta;
@@ -1455,31 +1464,23 @@ GNUNET_FS_search_stop (struct GNUNET_FS_SearchContext *sc)
1455{ 1464{
1456 struct GNUNET_FS_ProgressInfo pi; 1465 struct GNUNET_FS_ProgressInfo pi;
1457 unsigned int i; 1466 unsigned int i;
1458 struct GNUNET_FS_SearchContext *parent;
1459 1467
1460 if (sc->top != NULL) 1468 if (sc->top != NULL)
1461 GNUNET_FS_end_top (sc->h, sc->top); 1469 GNUNET_FS_end_top (sc->h, sc->top);
1462 if (NULL != (parent = sc->parent)) 1470 if (sc->psearch_result != NULL)
1463 { 1471 sc->psearch_result->update_search = NULL;
1464 GNUNET_CONTAINER_DLL_remove (parent->child_head,
1465 parent->child_tail,
1466 sc);
1467 sc->parent = NULL;
1468 }
1469 while (NULL != sc->child_head)
1470 GNUNET_FS_search_stop (sc->child_head);
1471 GNUNET_CONTAINER_multihashmap_iterate (sc->master_result_map, 1472 GNUNET_CONTAINER_multihashmap_iterate (sc->master_result_map,
1472 &search_result_free, 1473 &search_result_free,
1473 sc); 1474 sc);
1474 if (sc->serialization != NULL) 1475 if (sc->serialization != NULL)
1475 { 1476 {
1476 GNUNET_FS_remove_sync_file_ (sc->h, 1477 GNUNET_FS_remove_sync_file_ (sc->h,
1477 (sc->parent != NULL) 1478 (sc->psearch_result != NULL)
1478 ? GNUNET_FS_SYNC_PATH_CHILD_SEARCH 1479 ? GNUNET_FS_SYNC_PATH_CHILD_SEARCH
1479 : GNUNET_FS_SYNC_PATH_MASTER_SEARCH, 1480 : GNUNET_FS_SYNC_PATH_MASTER_SEARCH,
1480 sc->serialization); 1481 sc->serialization);
1481 GNUNET_FS_remove_sync_dir_ (sc->h, 1482 GNUNET_FS_remove_sync_dir_ (sc->h,
1482 (sc->parent != NULL) 1483 (sc->psearch_result != NULL)
1483 ? GNUNET_FS_SYNC_PATH_CHILD_SEARCH 1484 ? GNUNET_FS_SYNC_PATH_CHILD_SEARCH
1484 : GNUNET_FS_SYNC_PATH_MASTER_SEARCH, 1485 : GNUNET_FS_SYNC_PATH_MASTER_SEARCH,
1485 sc->serialization); 1486 sc->serialization);
diff --git a/src/include/gnunet_fs_service.h b/src/include/gnunet_fs_service.h
index 2207e274e..d40ae4ef7 100644
--- a/src/include/gnunet_fs_service.h
+++ b/src/include/gnunet_fs_service.h
@@ -21,10 +21,6 @@
21 * @file include/gnunet_fs_service.h 21 * @file include/gnunet_fs_service.h
22 * @brief API for file-sharing via GNUnet 22 * @brief API for file-sharing via GNUnet
23 * @author Christian Grothoff 23 * @author Christian Grothoff
24 *
25 * TODO:
26 * - extend API with support for publish simulation (-s)
27 * and URI-argument binding to keyword/namespace (-u)
28 */ 24 */
29#ifndef GNUNET_FS_LIB_H 25#ifndef GNUNET_FS_LIB_H
30#define GNUNET_FS_LIB_H 26#define GNUNET_FS_LIB_H
@@ -1078,8 +1074,10 @@ struct GNUNET_FS_ProgressInfo
1078 1074
1079 /** 1075 /**
1080 * Client parent-context pointer; NULL for top-level searches, 1076 * Client parent-context pointer; NULL for top-level searches,
1081 * non-NULL for automatically triggered searches for updates in 1077 * refers to the client context of the associated search result
1082 * namespaces. 1078 * for automatically triggered searches for updates in
1079 * namespaces. In this case, 'presult' refers to that search
1080 * result.
1083 */ 1081 */
1084 void *pctx; 1082 void *pctx;
1085 1083