aboutsummaryrefslogtreecommitdiff
path: root/src/fs/fs_download.c
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2012-03-23 16:26:11 +0000
committerChristian Grothoff <christian@grothoff.org>2012-03-23 16:26:11 +0000
commitaf9ebccd1d30144d10af1adf0e9475278a9b0441 (patch)
tree582a23150d963f762081f481ffbfc4025707a162 /src/fs/fs_download.c
parentd0818f55815212dde381bd1a65a67f4d7d6124ff (diff)
downloadgnunet-af9ebccd1d30144d10af1adf0e9475278a9b0441.tar.gz
gnunet-af9ebccd1d30144d10af1adf0e9475278a9b0441.zip
-eliminating duplicate code
Diffstat (limited to 'src/fs/fs_download.c')
-rw-r--r--src/fs/fs_download.c157
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 */
2035struct GNUNET_FS_DownloadContext * 2021struct GNUNET_FS_DownloadContext *
2036GNUNET_FS_download_start (struct GNUNET_FS_Handle *h, 2022create_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 */
2108struct GNUNET_FS_DownloadContext *
2109GNUNET_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