diff options
author | Christian Grothoff <christian@grothoff.org> | 2012-03-23 16:26:11 +0000 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2012-03-23 16:26:11 +0000 |
commit | af9ebccd1d30144d10af1adf0e9475278a9b0441 (patch) | |
tree | 582a23150d963f762081f481ffbfc4025707a162 /src/fs/fs_download.c | |
parent | d0818f55815212dde381bd1a65a67f4d7d6124ff (diff) | |
download | gnunet-af9ebccd1d30144d10af1adf0e9475278a9b0441.tar.gz gnunet-af9ebccd1d30144d10af1adf0e9475278a9b0441.zip |
-eliminating duplicate code
Diffstat (limited to 'src/fs/fs_download.c')
-rw-r--r-- | src/fs/fs_download.c | 157 |
1 files changed, 73 insertions, 84 deletions
diff --git a/src/fs/fs_download.c b/src/fs/fs_download.c index 490beef5e..d91c9e824 100644 --- a/src/fs/fs_download.c +++ b/src/fs/fs_download.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | This file is part of GNUnet. | 2 | This file is part of GNUnet. |
3 | (C) 2001-2011 Christian Grothoff (and other contributing authors) | 3 | (C) 2001-2012 Christian Grothoff (and other contributing authors) |
4 | 4 | ||
5 | GNUnet is free software; you can redistribute it and/or modify | 5 | GNUnet is free software; you can redistribute it and/or modify |
6 | it under the terms of the GNU General Public License as published | 6 | it under the terms of the GNU General Public License as published |
@@ -21,9 +21,6 @@ | |||
21 | * @file fs/fs_download.c | 21 | * @file fs/fs_download.c |
22 | * @brief download methods | 22 | * @brief download methods |
23 | * @author Christian Grothoff | 23 | * @author Christian Grothoff |
24 | * | ||
25 | * TODO: | ||
26 | * - different priority for scheduling probe downloads? | ||
27 | */ | 24 | */ |
28 | #include "platform.h" | 25 | #include "platform.h" |
29 | #include "gnunet_constants.h" | 26 | #include "gnunet_constants.h" |
@@ -2003,16 +2000,7 @@ GNUNET_FS_download_signal_suspend_ (void *cls) | |||
2003 | 2000 | ||
2004 | 2001 | ||
2005 | /** | 2002 | /** |
2006 | * Download parts of a file. Note that this will store | 2003 | * Helper function to setup the download context. |
2007 | * the blocks at the respective offset in the given file. Also, the | ||
2008 | * download is still using the blocking of the underlying FS | ||
2009 | * encoding. As a result, the download may *write* outside of the | ||
2010 | * given boundaries (if offset and length do not match the 32k FS | ||
2011 | * block boundaries). <p> | ||
2012 | * | ||
2013 | * This function should be used to focus a download towards a | ||
2014 | * particular portion of the file (optimization), not to strictly | ||
2015 | * limit the download to exactly those bytes. | ||
2016 | * | 2004 | * |
2017 | * @param h handle to the file sharing subsystem | 2005 | * @param h handle to the file sharing subsystem |
2018 | * @param uri the URI of the file (determines what to download); CHK or LOC URI | 2006 | * @param uri the URI of the file (determines what to download); CHK or LOC URI |
@@ -2028,38 +2016,27 @@ GNUNET_FS_download_signal_suspend_ (void *cls) | |||
2028 | * @param anonymity anonymity level to use for the download | 2016 | * @param anonymity anonymity level to use for the download |
2029 | * @param options various options | 2017 | * @param options various options |
2030 | * @param cctx initial value for the client context for this download | 2018 | * @param cctx initial value for the client context for this download |
2031 | * @param parent parent download to associate this download with (use NULL | ||
2032 | * for top-level downloads; useful for manually-triggered recursive downloads) | ||
2033 | * @return context that can be used to control this download | 2019 | * @return context that can be used to control this download |
2034 | */ | 2020 | */ |
2035 | struct GNUNET_FS_DownloadContext * | 2021 | struct GNUNET_FS_DownloadContext * |
2036 | GNUNET_FS_download_start (struct GNUNET_FS_Handle *h, | 2022 | create_download_context (struct GNUNET_FS_Handle *h, |
2037 | const struct GNUNET_FS_Uri *uri, | 2023 | const struct GNUNET_FS_Uri *uri, |
2038 | const struct GNUNET_CONTAINER_MetaData *meta, | 2024 | const struct GNUNET_CONTAINER_MetaData *meta, |
2039 | const char *filename, const char *tempname, | 2025 | const char *filename, const char *tempname, |
2040 | uint64_t offset, uint64_t length, uint32_t anonymity, | 2026 | uint64_t offset, uint64_t length, uint32_t anonymity, |
2041 | enum GNUNET_FS_DownloadOptions options, void *cctx, | 2027 | enum GNUNET_FS_DownloadOptions options, void *cctx) |
2042 | struct GNUNET_FS_DownloadContext *parent) | ||
2043 | { | 2028 | { |
2044 | struct GNUNET_FS_DownloadContext *dc; | 2029 | struct GNUNET_FS_DownloadContext *dc; |
2045 | 2030 | ||
2046 | GNUNET_assert (GNUNET_FS_uri_test_chk (uri) || GNUNET_FS_uri_test_loc (uri)); | 2031 | GNUNET_assert (GNUNET_FS_uri_test_chk (uri) || GNUNET_FS_uri_test_loc (uri)); |
2047 | |||
2048 | if ((offset + length < offset) || | 2032 | if ((offset + length < offset) || |
2049 | (offset + length > GNUNET_FS_uri_chk_get_file_size (uri))) | 2033 | (offset + length > GNUNET_FS_uri_chk_get_file_size (uri))) |
2050 | { | 2034 | { |
2051 | GNUNET_break (0); | 2035 | GNUNET_break (0); |
2052 | return NULL; | 2036 | return NULL; |
2053 | } | 2037 | } |
2054 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Starting download `%s' of %llu bytes\n", | ||
2055 | filename, (unsigned long long) length); | ||
2056 | dc = GNUNET_malloc (sizeof (struct GNUNET_FS_DownloadContext)); | 2038 | dc = GNUNET_malloc (sizeof (struct GNUNET_FS_DownloadContext)); |
2057 | dc->h = h; | 2039 | dc->h = h; |
2058 | dc->parent = parent; | ||
2059 | if (parent != NULL) | ||
2060 | { | ||
2061 | GNUNET_CONTAINER_DLL_insert (parent->child_head, parent->child_tail, dc); | ||
2062 | } | ||
2063 | dc->uri = GNUNET_FS_uri_dup (uri); | 2040 | dc->uri = GNUNET_FS_uri_dup (uri); |
2064 | dc->meta = GNUNET_CONTAINER_meta_data_duplicate (meta); | 2041 | dc->meta = GNUNET_CONTAINER_meta_data_duplicate (meta); |
2065 | dc->client_info = cctx; | 2042 | dc->client_info = cctx; |
@@ -2081,22 +2058,74 @@ GNUNET_FS_download_start (struct GNUNET_FS_Handle *h, | |||
2081 | GNUNET_CONTAINER_multihashmap_create (1 + 2 * (length / DBLOCK_SIZE)); | 2058 | GNUNET_CONTAINER_multihashmap_create (1 + 2 * (length / DBLOCK_SIZE)); |
2082 | dc->treedepth = | 2059 | dc->treedepth = |
2083 | GNUNET_FS_compute_depth (GNUNET_FS_uri_chk_get_file_size (dc->uri)); | 2060 | GNUNET_FS_compute_depth (GNUNET_FS_uri_chk_get_file_size (dc->uri)); |
2084 | if ((filename == NULL) && (is_recursive_download (dc))) | 2061 | if ((NULL == filename) && (is_recursive_download (dc))) |
2085 | { | 2062 | { |
2086 | if (tempname != NULL) | 2063 | if (NULL != tempname) |
2087 | dc->temp_filename = GNUNET_strdup (tempname); | 2064 | dc->temp_filename = GNUNET_strdup (tempname); |
2088 | else | 2065 | else |
2089 | dc->temp_filename = GNUNET_DISK_mktemp ("gnunet-directory-download-tmp"); | 2066 | dc->temp_filename = GNUNET_DISK_mktemp ("gnunet-directory-download-tmp"); |
2090 | } | 2067 | } |
2091 | 2068 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | |
2092 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Download tree has depth %u\n", | 2069 | "Starting download `%s' of %llu bytes with tree depth %u\n", |
2070 | filename, | ||
2071 | (unsigned long long) length, | ||
2093 | dc->treedepth); | 2072 | dc->treedepth); |
2094 | if (parent == NULL) | 2073 | dc->task = GNUNET_SCHEDULER_add_now (&GNUNET_FS_download_start_task_, dc); |
2095 | { | 2074 | return dc; |
2075 | } | ||
2076 | |||
2077 | |||
2078 | /** | ||
2079 | * Download parts of a file. Note that this will store | ||
2080 | * the blocks at the respective offset in the given file. Also, the | ||
2081 | * download is still using the blocking of the underlying FS | ||
2082 | * encoding. As a result, the download may *write* outside of the | ||
2083 | * given boundaries (if offset and length do not match the 32k FS | ||
2084 | * block boundaries). <p> | ||
2085 | * | ||
2086 | * This function should be used to focus a download towards a | ||
2087 | * particular portion of the file (optimization), not to strictly | ||
2088 | * limit the download to exactly those bytes. | ||
2089 | * | ||
2090 | * @param h handle to the file sharing subsystem | ||
2091 | * @param uri the URI of the file (determines what to download); CHK or LOC URI | ||
2092 | * @param meta known metadata for the file (can be NULL) | ||
2093 | * @param filename where to store the file, maybe NULL (then no file is | ||
2094 | * created on disk and data must be grabbed from the callbacks) | ||
2095 | * @param tempname where to store temporary file data, not used if filename is non-NULL; | ||
2096 | * can be NULL (in which case we will pick a name if needed); the temporary file | ||
2097 | * may already exist, in which case we will try to use the data that is there and | ||
2098 | * if it is not what is desired, will overwrite it | ||
2099 | * @param offset at what offset should we start the download (typically 0) | ||
2100 | * @param length how many bytes should be downloaded starting at offset | ||
2101 | * @param anonymity anonymity level to use for the download | ||
2102 | * @param options various options | ||
2103 | * @param cctx initial value for the client context for this download | ||
2104 | * @param parent parent download to associate this download with (use NULL | ||
2105 | * for top-level downloads; useful for manually-triggered recursive downloads) | ||
2106 | * @return context that can be used to control this download | ||
2107 | */ | ||
2108 | struct GNUNET_FS_DownloadContext * | ||
2109 | GNUNET_FS_download_start (struct GNUNET_FS_Handle *h, | ||
2110 | const struct GNUNET_FS_Uri *uri, | ||
2111 | const struct GNUNET_CONTAINER_MetaData *meta, | ||
2112 | const char *filename, const char *tempname, | ||
2113 | uint64_t offset, uint64_t length, uint32_t anonymity, | ||
2114 | enum GNUNET_FS_DownloadOptions options, void *cctx, | ||
2115 | struct GNUNET_FS_DownloadContext *parent) | ||
2116 | { | ||
2117 | struct GNUNET_FS_DownloadContext *dc; | ||
2118 | |||
2119 | dc = create_download_context (h, uri, meta, filename, tempname, | ||
2120 | offset, length, anonymity, options, cctx); | ||
2121 | if (NULL == dc) | ||
2122 | return NULL; | ||
2123 | dc->parent = parent; | ||
2124 | if (NULL != parent) | ||
2125 | GNUNET_CONTAINER_DLL_insert (parent->child_head, parent->child_tail, dc); | ||
2126 | else | ||
2096 | dc->top = | 2127 | dc->top = |
2097 | GNUNET_FS_make_top (dc->h, &GNUNET_FS_download_signal_suspend_, dc); | 2128 | GNUNET_FS_make_top (dc->h, &GNUNET_FS_download_signal_suspend_, dc); |
2098 | } | ||
2099 | dc->task = GNUNET_SCHEDULER_add_now (&GNUNET_FS_download_start_task_, dc); | ||
2100 | return dc; | 2129 | return dc; |
2101 | } | 2130 | } |
2102 | 2131 | ||
@@ -2146,62 +2175,22 @@ GNUNET_FS_download_start_from_search (struct GNUNET_FS_Handle *h, | |||
2146 | { | 2175 | { |
2147 | struct GNUNET_FS_DownloadContext *dc; | 2176 | struct GNUNET_FS_DownloadContext *dc; |
2148 | 2177 | ||
2149 | if ((sr == NULL) || (sr->download != NULL)) | 2178 | if ((NULL == sr) || (NULL != sr->download)) |
2150 | { | 2179 | { |
2151 | GNUNET_break (0); | 2180 | GNUNET_break (0); |
2152 | return NULL; | 2181 | return NULL; |
2153 | } | 2182 | } |
2154 | GNUNET_assert (GNUNET_FS_uri_test_chk (sr->uri) || | 2183 | dc = create_download_context (h, sr->uri, sr->meta, filename, tempname, |
2155 | GNUNET_FS_uri_test_loc (sr->uri)); | 2184 | offset, length, anonymity, options, cctx); |
2156 | if ((offset + length < offset) || | 2185 | if (NULL == dc) |
2157 | (offset + length > sr->uri->data.chk.file_length)) | ||
2158 | { | ||
2159 | GNUNET_break (0); | ||
2160 | return NULL; | 2186 | return NULL; |
2161 | } | ||
2162 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Starting download `%s' of %llu bytes\n", | ||
2163 | filename, (unsigned long long) length); | ||
2164 | dc = GNUNET_malloc (sizeof (struct GNUNET_FS_DownloadContext)); | ||
2165 | dc->h = h; | ||
2166 | dc->search = sr; | 2187 | dc->search = sr; |
2167 | sr->download = dc; | 2188 | sr->download = dc; |
2168 | if (sr->probe_ctx != NULL) | 2189 | if (NULL != sr->probe_ctx) |
2169 | { | 2190 | { |
2170 | GNUNET_FS_download_stop (sr->probe_ctx, GNUNET_YES); | 2191 | GNUNET_FS_download_stop (sr->probe_ctx, GNUNET_YES); |
2171 | sr->probe_ctx = NULL; | 2192 | sr->probe_ctx = NULL; |
2172 | } | 2193 | } |
2173 | dc->uri = GNUNET_FS_uri_dup (sr->uri); | ||
2174 | dc->meta = GNUNET_CONTAINER_meta_data_duplicate (sr->meta); | ||
2175 | dc->client_info = cctx; | ||
2176 | dc->start_time = GNUNET_TIME_absolute_get (); | ||
2177 | if (NULL != filename) | ||
2178 | { | ||
2179 | dc->filename = GNUNET_strdup (filename); | ||
2180 | if (GNUNET_YES == GNUNET_DISK_file_test (filename)) | ||
2181 | GNUNET_break (GNUNET_OK == GNUNET_DISK_file_size (filename, &dc->old_file_size, GNUNET_YES, GNUNET_YES)); | ||
2182 | } | ||
2183 | if (GNUNET_FS_uri_test_loc (dc->uri)) | ||
2184 | GNUNET_assert (GNUNET_OK == | ||
2185 | GNUNET_FS_uri_loc_get_peer_identity (dc->uri, &dc->target)); | ||
2186 | dc->offset = offset; | ||
2187 | dc->length = length; | ||
2188 | dc->anonymity = anonymity; | ||
2189 | dc->options = options; | ||
2190 | dc->active = | ||
2191 | GNUNET_CONTAINER_multihashmap_create (1 + 2 * (length / DBLOCK_SIZE)); | ||
2192 | dc->treedepth = | ||
2193 | GNUNET_FS_compute_depth (GNUNET_ntohll (dc->uri->data.chk.file_length)); | ||
2194 | if ((filename == NULL) && (is_recursive_download (dc))) | ||
2195 | { | ||
2196 | if (tempname != NULL) | ||
2197 | dc->temp_filename = GNUNET_strdup (tempname); | ||
2198 | else | ||
2199 | dc->temp_filename = GNUNET_DISK_mktemp ("gnunet-directory-download-tmp"); | ||
2200 | } | ||
2201 | |||
2202 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Download tree has depth %u\n", | ||
2203 | dc->treedepth); | ||
2204 | dc->task = GNUNET_SCHEDULER_add_now (&GNUNET_FS_download_start_task_, dc); | ||
2205 | return dc; | 2194 | return dc; |
2206 | } | 2195 | } |
2207 | 2196 | ||