$treeview $search $mathjax $extrastylesheet
librsync
2.3.1
$projectbrief
|
$projectbrief
|
$searchbox |
00001 /*= -*- c-basic-offset: 4; indent-tabs-mode: nil; -*- 00002 * 00003 * librsync -- library for network deltas 00004 * 00005 * Copyright 1999-2001, 2014, 2015 by Martin Pool <mbp@sourcefrog.net> 00006 * Copyright (C) 1999 by Andrew Tridgell <tridge@samba.org> 00007 * 00008 * This program is free software; you can redistribute it and/or modify 00009 * it under the terms of the GNU Lesser General Public License as published by 00010 * the Free Software Foundation; either version 2.1 of the License, or 00011 * (at your option) any later version. 00012 * 00013 * This program is distributed in the hope that it will be useful, 00014 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00015 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00016 * GNU Lesser General Public License for more details. 00017 * 00018 * You should have received a copy of the GNU Lesser General Public License 00019 * along with this program; if not, write to the Free Software 00020 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 00021 */ 00022 00023 /** \file mksum.c 00024 * Generate file signatures. 00025 * 00026 * Generating checksums is pretty easy, since we can always just process 00027 * whatever data is available. When a whole block has arrived, or we've reached 00028 * the end of the file, we write the checksum out. */ 00029 00030 #include "config.h" 00031 #include <assert.h> 00032 #include <stdlib.h> 00033 #include "librsync.h" 00034 #include "job.h" 00035 #include "sumset.h" 00036 #include "stream.h" 00037 #include "netint.h" 00038 #include "trace.h" 00039 #include "util.h" 00040 00041 /* Possible state functions for signature generation. */ 00042 static rs_result rs_sig_s_header(rs_job_t *); 00043 static rs_result rs_sig_s_generate(rs_job_t *); 00044 00045 /** State of trying to send the signature header. \private */ 00046 static rs_result rs_sig_s_header(rs_job_t *job) 00047 { 00048 rs_signature_t *sig = job->signature; 00049 rs_result result; 00050 00051 if ((result = 00052 rs_signature_init(sig, job->sig_magic, job->sig_block_len, 00053 job->sig_strong_len, 0)) != RS_DONE) 00054 return result; 00055 rs_squirt_n4(job, sig->magic); 00056 rs_squirt_n4(job, sig->block_len); 00057 rs_squirt_n4(job, sig->strong_sum_len); 00058 rs_trace("sent header (magic %#x, block len = %d, strong sum len = %d)", 00059 sig->magic, sig->block_len, sig->strong_sum_len); 00060 job->stats.block_len = sig->block_len; 00061 00062 job->statefn = rs_sig_s_generate; 00063 return RS_RUNNING; 00064 } 00065 00066 /** Generate the checksums for a block and write it out. Called when we 00067 * already know we have enough data in memory at \p block. \private */ 00068 static rs_result rs_sig_do_block(rs_job_t *job, const void *block, size_t len) 00069 { 00070 rs_signature_t *sig = job->signature; 00071 rs_weak_sum_t weak_sum; 00072 rs_strong_sum_t strong_sum; 00073 00074 weak_sum = rs_signature_calc_weak_sum(sig, block, len); 00075 rs_signature_calc_strong_sum(sig, block, len, &strong_sum); 00076 rs_squirt_n4(job, weak_sum); 00077 rs_tube_write(job, strong_sum, sig->strong_sum_len); 00078 if (rs_trace_enabled()) { 00079 char strong_sum_hex[RS_MAX_STRONG_SUM_LENGTH * 2 + 1]; 00080 rs_hexify(strong_sum_hex, strong_sum, sig->strong_sum_len); 00081 rs_trace("sent block: weak=" FMT_WEAKSUM ", strong=%s", weak_sum, 00082 strong_sum_hex); 00083 } 00084 job->stats.sig_blocks++; 00085 return RS_RUNNING; 00086 } 00087 00088 /** State of reading a block and trying to generate its sum. \private */ 00089 static rs_result rs_sig_s_generate(rs_job_t *job) 00090 { 00091 rs_result result; 00092 size_t len; 00093 void *block; 00094 00095 /* must get a whole block, otherwise try again */ 00096 len = job->signature->block_len; 00097 result = rs_scoop_read(job, len, &block); 00098 /* If we are near EOF, get whatever is left. */ 00099 if (result == RS_INPUT_ENDED) 00100 result = rs_scoop_read_rest(job, &len, &block); 00101 if (result == RS_INPUT_ENDED) { 00102 return RS_DONE; 00103 } else if (result != RS_DONE) { 00104 rs_trace("generate stopped: %s", rs_strerror(result)); 00105 return result; 00106 } 00107 rs_trace("got " FMT_SIZE " byte block", len); 00108 return rs_sig_do_block(job, block, len); 00109 } 00110 00111 rs_job_t *rs_sig_begin(size_t block_len, size_t strong_len, 00112 rs_magic_number sig_magic) 00113 { 00114 rs_job_t *job; 00115 00116 job = rs_job_new("signature", rs_sig_s_header); 00117 job->signature = rs_alloc_struct(rs_signature_t); 00118 job->job_owns_sig = 1; 00119 job->sig_magic = sig_magic; 00120 job->sig_block_len = block_len; 00121 job->sig_strong_len = strong_len; 00122 return job; 00123 }