static #endif int forward_before_entry(struct manio *manio, struct iobuf *target, struct cntr *cntr, struct dpth *dpth, enum protocol protocol, man_off_t **pos) { int ars=0; struct sbuf *sb=NULL; if(!(sb=sbuf_alloc(protocol))) goto error; man_off_t_free(pos); if(!(*pos=manio_tell(manio))) { logp("Could not manio_tell first pos in %s(): %s\n", __func__, strerror(errno)); goto error; } while(1) { if(sb->endfile.buf || (sb->path.buf && !sbuf_is_filedata(sb))) { man_off_t_free(pos); if(!(*pos=manio_tell(manio))) { logp("Could not manio_tell pos in %s(): " "%s\n", __func__, strerror(errno)); goto error; } } sbuf_free_content(sb); ars=manio_read(manio, sb); if(dpth && set_higher_datapth(sb, dpth)) goto error; switch(ars) { case 0: break; case 1: sbuf_free(&sb); return 0; default: logp("Error in %s(), but continuing\n", __func__); // Treat error in unchanged manio as // OK - could have been a short write. sbuf_free(&sb); return 0; } if(iobuf_pathcmp(target, &sb->path)<=0) { sbuf_free(&sb); return 0; } if(cntr) { cntr_add_same(cntr, sb->path.cmd); if(sb->endfile.buf) { uint64_t e=strtoull(sb->endfile.buf, NULL, 10); cntr_add_bytes(cntr, e); } } } error: sbuf_free(&sb); man_off_t_free(pos); return -1; }
// Like pathcmp, but sort entries that have the same paths so that metadata // comes later, and vss comes earlier, and trailing vss comes later. int sbuf_pathcmp(struct sbuf *a, struct sbuf *b) { return iobuf_pathcmp(&a->path, &b->path); }