static int hash_presence_callback(const char *hexhash, unsigned int index, int code, void *context) { hash_presence_ctx_t *ctx = (hash_presence_ctx_t*)context; sx_hashfs_t *h = ctx->h; sx_nodelist_t *nodes; sx_hash_t hash; if (code != 200) { if (code < 0) WARN("Failed to query hash %.*s: %s", 40, hexhash, sx_hashfs_geterrmsg(h)); if (hex2bin(hexhash, SXI_SHA1_TEXT_LEN, hash.b, sizeof(hash.b))) { WARN("hex2bin failed on %.*s", 40, hexhash); return -1; } nodes = sx_hashfs_putfile_hashnodes(h, &hash); if (!nodes) { WARN("hashnodes failed"); return -1; } if(ctx->comma) CGI_PUTC(','); else ctx->comma |= 1; DEBUG("Requesting from user: #%.*s#", 40, hexhash); send_qstring_hash(&hash); CGI_PUTC(':'); /* Although there is no danger in doing so, nodes SHOULD NOT be randomized: * hdist already does a pretty good job here */ send_nodes(nodes); sx_nodelist_delete(nodes); } send_keepalive(); return 0; }
void fcgi_send_file(void) { sx_hashfs_file_t filedata; const sx_hash_t *hash; sx_nodelist_t *nodes; sx_hash_t etag; int comma = 0; rc_ty s = sx_hashfs_getfile_begin(hashfs, volume, path, get_arg("rev"), &filedata, &etag); if(s != OK) quit_errnum(s == ENOENT ? 404 : 500); if(is_object_fresh(&etag, 'F', filedata.created_at)) { sx_hashfs_getfile_end(hashfs); return; } CGI_PRINTF("Content-type: application/json\r\n\r\n{\"blockSize\":%d,\"fileSize\":", filedata.block_size); CGI_PUTLL(filedata.file_size); CGI_PRINTF(",\"createdAt\":%u,\"fileRevision\":\"%s\",\"fileData\":[", filedata.created_at, filedata.revision); while((s = sx_hashfs_getfile_block(hashfs, &hash, &nodes)) == OK) { if(comma) CGI_PUTC(','); else comma |= 1; CGI_PUTC('{'); send_qstring_hash(hash); CGI_PUTC(':'); /* Nodes are in NL_PREVNEXT order and MUST NOT be randomized * (see comments in sx_hashfs_getfile_block) */ send_nodes(nodes); CGI_PUTC('}'); sx_nodelist_delete(nodes); } sx_hashfs_getfile_end(hashfs); CGI_PUTS("]"); if(s != ITER_NO_MORE) quit_itererr("Failed to list file blocks", s); CGI_PUTS("}"); }
int locate_cmp(sxi_hdist_t *model1, sxi_hdist_t *model2, uint64_t hash, int replica, int bidx) { sx_nodelist_t *nodelist1, *nodelist2; int i; nodelist1 = sxi_hdist_locate(model1, hash, replica, bidx); if(!nodelist1) { CRIT("Can't locate hash with model1"); return 1; } nodelist2 = sxi_hdist_locate(model2, hash, replica, bidx); if(!nodelist1) { CRIT("Can't locate hash with model2"); sx_nodelist_delete(nodelist1); return 1; } if(sx_nodelist_count(nodelist1) != sx_nodelist_count(nodelist2) || sx_nodelist_count(nodelist1) != replica) { CRIT("Numbers of target nodes don't match"); sx_nodelist_delete(nodelist1); sx_nodelist_delete(nodelist2); return 1; } if(dbg) fprintf(stderr, "Locate (hash: %llx, replica: %u, bidx: %d) = ", (unsigned long long) hash, replica, bidx); for(i = 0; i < sx_nodelist_count(nodelist1); i++) { if(strcmp(sx_node_uuid_str(sx_nodelist_get(nodelist1, i)), sx_node_uuid_str(sx_nodelist_get(nodelist2, i)))) { CRIT("Different nodes reported for duplicate models"); sx_nodelist_delete(nodelist1); sx_nodelist_delete(nodelist2); return 1; } if(dbg) fprintf(stderr, "%s ", sx_node_addr(sx_nodelist_get(nodelist1, i))); } if(dbg) fprintf(stderr, "\n"); sx_nodelist_delete(nodelist1); sx_nodelist_delete(nodelist2); return 0; }