int protocol2_extra_restore_stream_bits(struct asfd *asfd, struct blk *blk, struct slist *slist, enum action act, struct sbuf *need_data, int last_ent_was_dir, struct cntr *cntr) { int ret=-1; if(need_data->path.buf) { ret=send_data(asfd, blk, act, need_data, cntr); } else if(last_ent_was_dir) { // Careful, blk is not allocating blk->data and the data there // can get changed if we try to keep it for later. So, need to // allocate new space and copy the bytes. struct blk *nblk; struct sbuf *xb; if(!(nblk=blk_alloc_with_data(blk->length))) goto end; nblk->length=blk->length; memcpy(nblk->data, blk->data, blk->length); xb=slist->head; if(!xb->protocol2->bstart) xb->protocol2->bstart=xb->protocol2->bend=nblk; else { xb->protocol2->bend->next=nblk; xb->protocol2->bend=nblk; } ret=0; } else { logw(asfd, cntr, "Unexpected signature in manifest: %016" PRIX64 "%s%s\n", blk->fingerprint, bytes_to_md5str(blk->md5sum), uint64_to_savepathstr_with_sig(blk->savepath)); } end: blk->data=NULL; return ret; }
// The client uses this. // Return 0 for OK. 1 for OK, and file ended, -1 for error. int blks_generate(struct asfd *asfd, struct conf **confs, struct sbuf *sb, struct blist *blist, int just_opened) { static ssize_t bytes; first=just_opened; if(!blk && !(blk=blk_alloc_with_data(rconf.blk_max))) return -1; if(gcp<gbuf_end) { // Could have got a fill before buf ran out - // need to resume from the same place in that case. if(blk_read_to_list(sb, blist)) return 0; // Got a block. // Did not get a block. Carry on and read more. } while((bytes=rabin_read(sb, gbuf, rconf.blk_max))) { gcp=gbuf; gbuf_end=gbuf+bytes; sb->protocol2->bytes_read+=bytes; if(blk_read_to_list(sb, blist)) return 0; // Got a block // Did not get a block. Maybe should try again? // If there are async timeouts, look at this! return 0; } // Getting here means there is no more to read from the file. // Make sure to deal with anything left over. if(!sb->protocol2->bytes_read) { // Empty file, set up an empty block so that the server // can skip over it. if(!(sb->protocol2->bstart=blk_alloc())) return -1; sb->protocol2->bsighead=blk; blist_add_blk(blist, blk); blk=NULL; } else if(blk) { if(blk->length) { if(first) { sb->protocol2->bstart=blk; first=0; } if(!sb->protocol2->bsighead) { sb->protocol2->bsighead=blk; } blist_add_blk(blist, blk); } else blk_free(&blk); blk=NULL; } if(blist->tail) sb->protocol2->bend=blist->tail; return 1; }