When called by the sender, read the request from the generator and mark * any needed xattrs with a flag that lets us know they need to be sent to * the receiver. When called by the receiver, reads the sent data and * stores it in place of its checksum. */
| 679 | * the receiver. When called by the receiver, reads the sent data and |
| 680 | * stores it in place of its checksum. */ |
| 681 | int recv_xattr_request(struct file_struct *file, int f_in) |
| 682 | { |
| 683 | const rsync_xa_list *glst = rsync_xal_l.items; |
| 684 | const item_list *lst; |
| 685 | char *old_datum, *name; |
| 686 | rsync_xa *rxa; |
| 687 | int rel_pos, cnt, num, got_xattr_data = 0; |
| 688 | |
| 689 | if (F_XATTR(file) < 0) { |
| 690 | rprintf(FERROR, "recv_xattr_request: internal data error!\n"); |
| 691 | exit_cleanup(RERR_PROTOCOL); |
| 692 | } |
| 693 | glst += F_XATTR(file); |
| 694 | lst = &glst->xa_items; |
| 695 | |
| 696 | cnt = lst->count; |
| 697 | rxa = lst->items; |
| 698 | num = 0; |
| 699 | while ((rel_pos = read_varint(f_in)) != 0) { |
| 700 | /* Detect signed overflow before the accumulating add. A hostile |
| 701 | * peer could otherwise wrap 'num' to land on an arbitrary value. */ |
| 702 | if ((rel_pos > 0 && num > INT_MAX - rel_pos) |
| 703 | || (rel_pos < 0 && num < INT_MIN - rel_pos)) { |
| 704 | rprintf(FERROR, "xattr rel_pos accumulation overflow [%s]\n", who_am_i()); |
| 705 | exit_cleanup(RERR_PROTOCOL); |
| 706 | } |
| 707 | num += rel_pos; |
| 708 | if (am_sender) { |
| 709 | /* The sender-related num values are only in order on the sender. |
| 710 | * We use that order here to scan forward or backward as needed. */ |
| 711 | if (rel_pos < 0) { |
| 712 | while (cnt < (int)lst->count && rxa->num > num) { |
| 713 | rxa--; |
| 714 | cnt++; |
| 715 | } |
| 716 | } else { |
| 717 | while (cnt > 1 && rxa->num < num) { |
| 718 | rxa++; |
| 719 | cnt--; |
| 720 | } |
| 721 | } |
| 722 | } else { |
| 723 | int j; |
| 724 | /* The receiving side has no known num order, so we just scan |
| 725 | * forward (w/wrap) and hope that the next value is near by. */ |
| 726 | for (j = lst->count; j > 1 && rxa->num != num; j--) { |
| 727 | if (--cnt) |
| 728 | rxa++; |
| 729 | else { |
| 730 | cnt = lst->count; |
| 731 | rxa = lst->items; |
| 732 | } |
| 733 | } |
| 734 | } |
| 735 | if (!cnt || rxa->num != num) { |
| 736 | rprintf(FERROR, "[%s] could not find xattr #%d for %s\n", |
| 737 | who_am_i(), num, f_name(file, NULL)); |
| 738 | exit_cleanup(RERR_PROTOCOL); |
no test coverage detected