int csync_recv_file(FILE *out) { char buffer[512]; int rc, chunk; long size; if ( !conn_gets(buffer, 100) || sscanf(buffer, "octet-stream %ld\n", &size) != 1 ) { if (!strcmp(buffer, "ERROR\n")) { errno=EIO; return -1; } csync_fatal("Format-error while receiving data.\n"); } csync_debug(3, "Receiving %ld bytes ..\n", size); while ( size > 0 ) { chunk = size > 512 ? 512 : size; rc = conn_read(buffer, chunk); if ( rc <= 0 ) csync_fatal("Read-error while receiving data.\n"); chunk = rc; rc = fwrite(buffer, chunk, 1, out); if ( rc != 1 ) csync_fatal("Write-error while receiving data.\n"); size -= chunk; csync_debug(3, "Got %d bytes, %ld bytes left ..\n", chunk, size); } fflush(out); rewind(out); return 0; }
int csync_rs_check(const char *filename, int isreg) { FILE *basis_file = 0, *sig_file = 0; char buffer1[512], buffer2[512]; int rc, chunk, found_diff = 0; int backup_errno; rs_stats_t stats; rs_result result; long size; char tmpfname[MAXPATHLEN]; csync_debug(3, "Csync2 / Librsync: csync_rs_check('%s', %d [%s])\n", filename, isreg, isreg ? "regular file" : "non-regular file"); csync_debug(3, "Opening basis_file and sig_file..\n"); sig_file = open_temp_file(tmpfname, prefixsubst(filename)); if ( !sig_file ) goto io_error; if (unlink(tmpfname) < 0) goto io_error; basis_file = fopen(prefixsubst(filename), "rb"); if ( !basis_file ) { /* ?? why a tmp file? */ basis_file = open_temp_file(tmpfname, prefixsubst(filename)); if ( !basis_file ) goto io_error; if (unlink(tmpfname) < 0) goto io_error; } if ( isreg ) { csync_debug(3, "Running rs_sig_file() from librsync....\n"); result = rs_sig_file(basis_file, sig_file, RS_DEFAULT_BLOCK_LEN, RS_DEFAULT_STRONG_LEN, &stats); if (result != RS_DONE) { csync_debug(0, "Internal error from rsync library!\n"); goto error; } } fclose(basis_file); basis_file = 0; { char line[100]; csync_debug(3, "Reading signature size from peer....\n"); if ( !conn_gets(line, 100) || sscanf(line, "octet-stream %ld\n", &size) != 1 ) csync_fatal("Format-error while receiving data.\n"); } fflush(sig_file); if ( size != ftell(sig_file) ) { csync_debug(2, "Signature size differs: local=%d, peer=%d\n", ftell(sig_file), size); found_diff = 1; } rewind(sig_file); csync_debug(3, "Receiving %ld bytes ..\n", size); while ( size > 0 ) { chunk = size > 512 ? 512 : size; rc = conn_read(buffer1, chunk); if ( rc <= 0 ) csync_fatal("Read-error while receiving data.\n"); chunk = rc; if ( fread(buffer2, chunk, 1, sig_file) != 1 ) { csync_debug(2, "Found EOF in local sig file.\n"); found_diff = 1; } if ( memcmp(buffer1, buffer2, chunk) ) { csync_debug(2, "Found diff in sig at -%d:-%d\n", size, size-chunk); found_diff = 1; } size -= chunk; csync_debug(3, "Got %d bytes, %ld bytes left ..\n", chunk, size); } csync_debug(3, "File has been checked successfully (%s).\n", found_diff ? "difference found" : "files are equal"); fclose(sig_file); return found_diff; io_error: csync_debug(0, "I/O Error '%s' in rsync-check: %s\n", strerror(errno), prefixsubst(filename)); error:; backup_errno = errno; if ( basis_file ) fclose(basis_file); if ( sig_file ) fclose(sig_file); errno = backup_errno; return -1; }
static int net_transfer_body_HTTP_1_1(struct conn* dst, struct conn* src, struct net_data* data) { if (strcmp(data->buf.p, "HEAD") == 0) return 0; int ret = 0; char* keyval = net_data_get_ent(data, "Transfer-Encoding"); if (keyval == NULL || strcmp(keyval, "chunked")) { // Not chunked encoding keyval = net_data_get_ent(data, "Content-Length"); int len = 0; if (keyval) len += atoi(keyval); if (len > 0) { ret = conn_copy(dst, src, len); if (ret) return ret; } return 0; } // Transfer-Encoding: chunked // FIXME HTTP rfc tells that proxy should forward decoded body struct strbuf buf; strbuf_init(&buf); while (1) { strbuf_reset(&buf); ret = conn_gets(src, HTTP_CHUNK_HEADER_MAXLEN, &buf); if (ret <= 0) { ret = -1; break; } strbuf_cat(&buf, "\r\n"); ret = conn_write(dst, buf.p, buf.len); if (ret) { break; } int len = -1; sscanf(buf.p, "%x", &len); if (len == 0) { // Last chunck ret = 0; break; } // Also copy the \r\n ret = conn_copy(dst, src, len+2); if (ret) break; } if (ret == 0) { // Chunked trailer part while (1) { strbuf_reset(&buf); ret = conn_gets(src, HTTP_HEADER_MAXLEN, &buf); if (ret < 0) return ret; strbuf_cat(&buf, "\r\n"); if (conn_write(dst, buf.p, buf.len)) { ret = -1; break; } if (ret == 0) break; } } strbuf_done(&buf); return ret; }