/*! ** @brief Checks the status of the specified CID. ** ** XgetChunkStatus returns an integer indicating if the specified content ** chunk is available to be read. It is a simple wrapper around the ** XgetChunkStatuses() function which does the actual work. ** ** @note This function Should be called after calling XrequestChunk() or ** XrequestChunks(). Otherwise the content chunk will never be loaded into ** the content cache and will result in a REQUEST_FAILED error. ** ** @param sockfd the control socket (must be of type XSOCK_CHUNK) ** @param dag Content ID of the chunk to check. This should be a full dag ** for the desired chunk, not just the CID. ** @param dagLen length of dag (currently not used) ** ** @returns READY_TO_READ if the requested chunk is ready to be read. ** @returns INVALID_HASH if the CID hash does not match the content payload. ** @returns WAITING_FOR_CHUNK if the requested chunk is still in transit. ** @returns REQUEST_FAILED if the specified chunk has not been requested ** @returns -1 if a socket error occurs. In that case errno is set with the appropriate code. */ int XgetChunkStatus(int sockfd, char* dag, size_t /* dagLen */) { ChunkStatus cs; cs.cid = dag; cs.cidLen = strlen(dag); return XgetChunkStatuses(sockfd, &cs, 1); }
int getListedChunks(int csock, FILE *fd, char *chunks, char *p_ad, char *p_hid) { ChunkStatus cs[NUM_CHUNKS]; char data[XIA_MAXCHUNK]; int len; int status; int n = -1; n = buildChunkDAGs(cs, chunks, p_ad, p_hid); // NOTE: the chunk transport is not currently reliable and chunks may need to be re-requested // ask for the current chunk list again every REREQUEST seconds // chunks already in the local cache will not be refetched from the network unsigned ctr = 0; while (1) { if (ctr % REREQUEST == 0) { // bring the list of chunks local say("%srequesting list of %d chunks\n", (ctr == 0 ? "" : "re-"), n); if (XrequestChunks(csock, cs, n) < 0) { say("unable to request chunks\n"); return -1; } say("checking chunk status\n"); ctr++; } status = XgetChunkStatuses(csock, cs, n); if (status == READY_TO_READ) break; else if (status < 0) { say("error getting chunk status\n"); return -1; } else if (status & WAITING_FOR_CHUNK) { // one or more chunks aren't ready. say("waiting... one or more chunks aren't ready yet\n"); } else if (status & INVALID_HASH) { die(-1, "one or more chunks has an invalid hash"); } else if (status & REQUEST_FAILED) { die(-1, "no chunks found\n"); } else { say("unexpected result\n"); } sleep(1); } say("all chunks ready\n"); for (int i = 0; i < n; i++) { char *cid = strrchr(cs[i].cid, ':'); cid++; say("reading chunk %s\n", cid); if ((len = XreadChunk(csock, data, sizeof(data), 0, cs[i].cid, cs[i].cidLen)) < 0) { say("error getting chunk\n"); return -1; } // write the chunk to disk // say("writing %d bytes of chunk %s to disk\n", len, cid); fwrite(data, 1, len, fd); free(cs[i].cid); cs[i].cid = NULL; cs[i].cidLen = 0; } return n; }
int getListedChunks(int csock, FILE *fd, char *chunks, char *p_ad, char *p_hid) { ChunkStatus cs[NUM_CHUNKS]; char data[XIA_MAXCHUNK]; int len; int status; int n = -1; n = buildChunkDAGs(cs, chunks, p_ad, p_hid); // bring the list of chunks local say("requesting list of %d chunks\n", n); if (XrequestChunks(csock, cs, n) < 0) { say("unable to request chunks\n"); return -1; } say("checking chunk status\n"); while (1) { status = XgetChunkStatuses(csock, cs, n); if (status == READY_TO_READ) break; else if (status < 0) { say("error getting chunk status\n"); return -1; } else if (status & WAITING_FOR_CHUNK) { // one or more chunks aren't ready. say("waiting... one or more chunks aren't ready yet\n"); } else if (status & INVALID_HASH) { die(-1, "one or more chunks has an invalid hash"); } else if (status & REQUEST_FAILED) { die(-1, "no chunks found\n"); } else { say("unexpected result\n"); } sleep(1); } say("all chunks ready\n"); for (int i = 0; i < n; i++) { char *cid = strrchr(cs[i].cid, ':'); cid++; say("reading chunk %s\n", cid); if ((len = XreadChunk(csock, data, sizeof(data), 0, cs[i].cid, cs[i].cidLen)) < 0) { say("error getting chunk\n"); return -1; } // write the chunk to disk // say("writing %d bytes of chunk %s to disk\n", len, cid); fwrite(data, 1, len, fd); free(cs[i].cid); cs[i].cid = NULL; cs[i].cidLen = 0; } return n; }