Receive a deflated token and inflate it */
| 565 | |
| 566 | /* Receive a deflated token and inflate it */ |
| 567 | static int32 recv_deflated_token(int f, char **data) |
| 568 | { |
| 569 | static int init_done; |
| 570 | static int32 saved_flag; |
| 571 | int32 n, flag; |
| 572 | int r; |
| 573 | |
| 574 | for (;;) { |
| 575 | switch (recv_state) { |
| 576 | case r_init: |
| 577 | if (!init_done) { |
| 578 | rx_strm.next_out = NULL; |
| 579 | rx_strm.zalloc = NULL; |
| 580 | rx_strm.zfree = NULL; |
| 581 | if (inflateInit2(&rx_strm, -15) != Z_OK) { |
| 582 | rprintf(FERROR, "inflate init failed\n"); |
| 583 | exit_cleanup(RERR_PROTOCOL); |
| 584 | } |
| 585 | cbuf = new_array(char, MAX_DATA_COUNT); |
| 586 | dbuf = new_array(char, AVAIL_OUT_SIZE(CHUNK_SIZE)); |
| 587 | init_done = 1; |
| 588 | } else { |
| 589 | inflateReset(&rx_strm); |
| 590 | } |
| 591 | recv_state = r_idle; |
| 592 | rx_token = 0; |
| 593 | break; |
| 594 | |
| 595 | case r_idle: |
| 596 | case r_inflated: |
| 597 | if (saved_flag) { |
| 598 | flag = saved_flag & 0xff; |
| 599 | saved_flag = 0; |
| 600 | } else |
| 601 | flag = read_byte(f); |
| 602 | if ((flag & 0xC0) == DEFLATED_DATA) { |
| 603 | n = ((flag & 0x3f) << 8) + read_byte(f); |
| 604 | read_buf(f, cbuf, n); |
| 605 | rx_strm.next_in = (Bytef *)cbuf; |
| 606 | rx_strm.avail_in = n; |
| 607 | recv_state = r_inflating; |
| 608 | break; |
| 609 | } |
| 610 | if (recv_state == r_inflated) { |
| 611 | /* check previous inflated stuff ended correctly */ |
| 612 | rx_strm.avail_in = 0; |
| 613 | rx_strm.next_out = (Bytef *)dbuf; |
| 614 | rx_strm.avail_out = AVAIL_OUT_SIZE(CHUNK_SIZE); |
| 615 | r = inflate(&rx_strm, Z_SYNC_FLUSH); |
| 616 | n = AVAIL_OUT_SIZE(CHUNK_SIZE) - rx_strm.avail_out; |
| 617 | /* |
| 618 | * Z_BUF_ERROR just means no progress was |
| 619 | * made, i.e. the decompressor didn't have |
| 620 | * any pending output for us. |
| 621 | */ |
| 622 | if (r != Z_OK && r != Z_BUF_ERROR) { |
| 623 | rprintf(FERROR, "inflate flush returned %d (%d bytes)\n", |
| 624 | r, n); |
no test coverage detected