- GNUNET_BIO_write_int32 (wh, (uint32_t) uc->state)) ||
- ( (uc->state == UNINDEX_STATE_FS_NOTIFY) &&
- (GNUNET_OK !=
- GNUNET_BIO_write (wh, &uc->file_id, sizeof (GNUNET_HashCode))) ) ||
- ( (uc->state == UNINDEX_STATE_ERROR) &&
- (GNUNET_OK !=
- GNUNET_BIO_write_string (wh, uc->emsg)) ) )
- {
- (void) GNUNET_BIO_write_close (wh);
- GNUNET_FS_remove_sync_file_ (uc->h, "publish", uc->serialization);
- GNUNET_free (uc->serialization);
- uc->serialization = NULL;
- return;
- }
- if (GNUNET_OK !=
- GNUNET_BIO_write_close (wh))
- {
- GNUNET_FS_remove_sync_file_ (uc->h, "unindex", uc->serialization);
- GNUNET_free (uc->serialization);
- uc->serialization = NULL;
- return;
- }
+ GNUNET_BIO_write (wh, &uc->file_id, sizeof (GNUNET_HashCode)))) ||
+ ((uc->state == UNINDEX_STATE_ERROR) &&
+ (GNUNET_OK != GNUNET_BIO_write_string (wh, uc->emsg))))
+ {
+ GNUNET_break (0);
+ goto cleanup;
+ }
+ if (GNUNET_OK != GNUNET_BIO_write_close (wh))
+ {
+ wh = NULL;
+ GNUNET_break (0);
+ goto cleanup;
+ }
+ return;
+cleanup:
+ if (wh != NULL)
+ (void) GNUNET_BIO_write_close (wh);
+ GNUNET_FS_remove_sync_file_ (uc->h, GNUNET_FS_SYNC_PATH_MASTER_UNINDEX,
+ uc->serialization);
+ GNUNET_free (uc->serialization);
+ uc->serialization = NULL;
+}
+
+
+/**
+ * Serialize a download request.
+ *
+ * @param wh the 'struct GNUNET_BIO_WriteHandle*'
+ * @param dr the 'struct DownloadRequest'
+ * @return GNUNET_YES on success, GNUNET_NO on error
+ */
+static int
+write_download_request (struct GNUNET_BIO_WriteHandle *wh,
+ struct DownloadRequest *dr)
+{
+ unsigned int i;
+
+ if ((GNUNET_OK != GNUNET_BIO_write_int32 (wh, dr->state)) ||
+ (GNUNET_OK != GNUNET_BIO_write_int64 (wh, dr->offset)) ||
+ (GNUNET_OK != GNUNET_BIO_write_int32 (wh, dr->num_children)) ||
+ (GNUNET_OK != GNUNET_BIO_write_int32 (wh, dr->depth)))
+ return GNUNET_NO;
+ if ((dr->state == BRS_CHK_SET) &&
+ (GNUNET_OK !=
+ GNUNET_BIO_write (wh, &dr->chk, sizeof (struct ContentHashKey))))
+ return GNUNET_NO;
+ for (i = 0; i < dr->num_children; i++)
+ if (GNUNET_NO == write_download_request (wh, dr->children[i]))
+ return GNUNET_NO;
+ return GNUNET_YES;
+}
+
+
+/**
+ * Read a download request tree.
+ *
+ * @param rh stream to read from
+ * @return value the 'struct DownloadRequest', NULL on error
+ */
+static struct DownloadRequest *
+read_download_request (struct GNUNET_BIO_ReadHandle *rh)
+{
+ struct DownloadRequest *dr;
+ unsigned int i;
+
+ dr = GNUNET_malloc (sizeof (struct DownloadRequest));
+
+ if ((GNUNET_OK != GNUNET_BIO_read_int32 (rh, &dr->state)) ||
+ (GNUNET_OK != GNUNET_BIO_read_int64 (rh, &dr->offset)) ||
+ (GNUNET_OK != GNUNET_BIO_read_int32 (rh, &dr->num_children)) ||
+ (dr->num_children > CHK_PER_INODE) ||
+ (GNUNET_OK != GNUNET_BIO_read_int32 (rh, &dr->depth)) || ((dr->depth == 0)
+ &&
+ (dr->num_children
+ > 0)) ||
+ ((dr->depth > 0) && (dr->num_children == 0)))
+ {
+ GNUNET_break (0);
+ dr->num_children = 0;
+ goto cleanup;
+ }
+ if (dr->num_children > 0)
+ dr->children =
+ GNUNET_malloc (dr->num_children * sizeof (struct ContentHashKey));
+ switch (dr->state)
+ {
+ case BRS_INIT:
+ case BRS_RECONSTRUCT_DOWN:
+ case BRS_RECONSTRUCT_META_UP:
+ case BRS_RECONSTRUCT_UP:
+ break;
+ case BRS_CHK_SET:
+ if (GNUNET_OK !=
+ GNUNET_BIO_read (rh, "chk", &dr->chk, sizeof (struct ContentHashKey)))
+ goto cleanup;
+ break;
+ case BRS_DOWNLOAD_DOWN:
+ case BRS_DOWNLOAD_UP:
+ case BRS_ERROR:
+ break;
+ default:
+ GNUNET_break (0);
+ goto cleanup;
+ }
+ for (i = 0; i < dr->num_children; i++)
+ {
+ if (NULL == (dr->children[i] = read_download_request (rh)))
+ goto cleanup;
+ dr->children[i]->parent = dr;
+ }
+ return dr;
+cleanup:
+ GNUNET_FS_free_download_request_ (dr);
+ return NULL;
+}
+
+
+/**
+ * Compute the name of the sync file (or directory) for the given download
+ * context.
+ *
+ * @param dc download context to compute for
+ * @param uni unique filename to use, use "" for the directory name
+ * @param ext extension to use, use ".dir" for our own subdirectory
+ * @return the expanded file name, NULL for none
+ */
+static char *
+get_download_sync_filename (struct GNUNET_FS_DownloadContext *dc,
+ const char *uni, const char *ext)
+{
+ char *par;
+ char *epar;
+
+ if (dc->parent == NULL)
+ return get_serialization_file_name (dc->h,
+ (dc->search !=
+ NULL) ?
+ GNUNET_FS_SYNC_PATH_CHILD_DOWNLOAD :
+ GNUNET_FS_SYNC_PATH_MASTER_DOWNLOAD,
+ uni);
+ if (dc->parent->serialization == NULL)
+ return NULL;
+ par = get_download_sync_filename (dc->parent, dc->parent->serialization, "");
+ if (par == NULL)
+ return NULL;
+ GNUNET_asprintf (&epar, "%s.dir%s%s%s", par, DIR_SEPARATOR_STR, uni, ext);
+ GNUNET_free (par);
+ return epar;