return;
if (dr->depth > 0)
{
+ if ( (dc->offset > 0) ||
+ (dc->length < GNUNET_ntohll (dc->uri->data.chk.file_length)) )
+ {
+ /* NOTE: this test is not tight, but should suffice; the issue
+ here is that 'dr->num_children' may inherently only specify a
+ smaller range than what is in the original file;
+ thus, reconstruction of (some) inner blocks will fail.
+ FIXME: we might eventually want to write a tighter test to
+ maximize the circumstances under which we do succeed with
+ IBlock reconstruction. (need good tests though). */
+ return;
+ }
complete = GNUNET_YES;
for (i = 0; i < dr->num_children; i++)
{
}
/* write block to disk */
fn = (NULL != dc->filename) ? dc->filename : dc->temp_filename;
- fh = GNUNET_DISK_file_open (fn,
- GNUNET_DISK_OPEN_READWRITE |
- GNUNET_DISK_OPEN_CREATE |
- GNUNET_DISK_OPEN_TRUNCATE,
- GNUNET_DISK_PERM_USER_READ |
- GNUNET_DISK_PERM_USER_WRITE |
- GNUNET_DISK_PERM_GROUP_READ |
- GNUNET_DISK_PERM_OTHER_READ);
- if (NULL == fh)
+ if (NULL != fn)
{
- GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR, "open", fn);
- GNUNET_asprintf (&dc->emsg, _("Failed to open file `%s' for writing"),
- fn);
- GNUNET_DISK_file_close (fh);
- dr->state = BRS_ERROR;
- pi.status = GNUNET_FS_STATUS_DOWNLOAD_ERROR;
- pi.value.download.specifics.error.message = dc->emsg;
- GNUNET_FS_download_make_status_ (&pi, dc);
- return;
- }
- if (data_len != GNUNET_DISK_file_write (fh, odata, odata_len))
- {
- GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR, "write", fn);
- GNUNET_asprintf (&dc->emsg, _("Failed to open file `%s' for writing"),
- fn);
+ fh = GNUNET_DISK_file_open (fn,
+ GNUNET_DISK_OPEN_READWRITE |
+ GNUNET_DISK_OPEN_CREATE |
+ GNUNET_DISK_OPEN_TRUNCATE,
+ GNUNET_DISK_PERM_USER_READ |
+ GNUNET_DISK_PERM_USER_WRITE |
+ GNUNET_DISK_PERM_GROUP_READ |
+ GNUNET_DISK_PERM_OTHER_READ);
+ if (NULL == fh)
+ {
+ GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR, "open", fn);
+ GNUNET_asprintf (&dc->emsg,
+ _("Failed to open file `%s' for writing"),
+ fn);
+ GNUNET_DISK_file_close (fh);
+ dr->state = BRS_ERROR;
+ pi.status = GNUNET_FS_STATUS_DOWNLOAD_ERROR;
+ pi.value.download.specifics.error.message = dc->emsg;
+ GNUNET_FS_download_make_status_ (&pi, dc);
+ return;
+ }
+ if (data_len != GNUNET_DISK_file_write (fh, odata, odata_len))
+ {
+ GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR, "write", fn);
+ GNUNET_asprintf (&dc->emsg, _("Failed to open file `%s' for writing"),
+ fn);
+ GNUNET_DISK_file_close (fh);
+ dr->state = BRS_ERROR;
+ pi.status = GNUNET_FS_STATUS_DOWNLOAD_ERROR;
+ pi.value.download.specifics.error.message = dc->emsg;
+ GNUNET_FS_download_make_status_ (&pi, dc);
+ return;
+ }
GNUNET_DISK_file_close (fh);
- dr->state = BRS_ERROR;
- pi.status = GNUNET_FS_STATUS_DOWNLOAD_ERROR;
- pi.value.download.specifics.error.message = dc->emsg;
- GNUNET_FS_download_make_status_ (&pi, dc);
- return;
}
- GNUNET_DISK_file_close (fh);
/* signal success */
dr->state = BRS_DOWNLOAD_UP;
dc->completed = dc->length;
* @param cls closure (our 'struct ProcessResultClosure')
* @param key query for the given value / request
* @param value value in the hash map (a 'struct DownloadRequest')
- * @return GNUNET_YES (we should continue to iterate); unless serious error
+ * @return #GNUNET_YES (we should continue to iterate); unless serious error
*/
static int
process_result_with_request (void *cls, const struct GNUNET_HashCode * key,
/**
* We must stop to ask the FS service for our blocks. Pause the download.
*
- * @param cls the 'struct GNUNET_FS_DownloadContext'
+ * @param cls the `struct GNUNET_FS_DownloadContext`
*/
static void
deactivate_fs_download (void *cls)
unsigned int head_skip;
uint64_t child_block_size;
- dr = GNUNET_malloc (sizeof (struct DownloadRequest));
+ dr = GNUNET_new (struct DownloadRequest);
dr->parent = parent;
dr->depth = depth;
dr->offset = dr_offset;
GNUNET_break (0);
return NULL;
}
- dc = GNUNET_malloc (sizeof (struct GNUNET_FS_DownloadContext));
+ dc = GNUNET_new (struct GNUNET_FS_DownloadContext);
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"Starting download %p, %u bytes at offset %llu\n",
dc,
{
GNUNET_FS_download_stop (sr->probe_ctx, GNUNET_YES);
sr->probe_ctx = NULL;
- }
- if (GNUNET_SCHEDULER_NO_TASK != sr->probe_ping_task)
- {
- GNUNET_SCHEDULER_cancel (sr->probe_ping_task);
- sr->probe_ping_task = GNUNET_SCHEDULER_NO_TASK;
+ GNUNET_FS_stop_probe_ping_task_ (sr);
}
return dc;
}
dc->job_queue);
}
+/**
+ * Suspend a download.
+ *
+ * @param dc handle for the download
+ */
+void
+GNUNET_FS_download_suspend (struct GNUNET_FS_DownloadContext *dc)
+{
+ deactivate_fs_download(dc);
+}
+
+/**
+ * Resume a suspended download.
+ *
+ * @param dc handle for the download
+ */
+void
+GNUNET_FS_download_resume (struct GNUNET_FS_DownloadContext *dc)
+{
+ struct GNUNET_FS_ProgressInfo pi;
+
+ pi.status = GNUNET_FS_STATUS_DOWNLOAD_ACTIVE;
+ GNUNET_FS_download_make_status_ (&pi, dc);
+
+ dc->job_queue =
+ GNUNET_FS_queue_ (dc->h, &activate_fs_download, &deactivate_fs_download,
+ dc, (dc->length + DBLOCK_SIZE - 1) / DBLOCK_SIZE,
+ (0 == (dc->options & GNUNET_FS_DOWNLOAD_IS_PROBE))
+ ? GNUNET_FS_QUEUE_PRIORITY_NORMAL
+ : GNUNET_FS_QUEUE_PRIORITY_PROBE);
+
+}
+
/**
* Stop a download (aborts if download is incomplete).