~ubuntu-branches/ubuntu/hardy/backuppc/hardy-security

« back to all changes in this revision

Viewing changes to lib/BackupPC/Xfer/RsyncDigest.pm

  • Committer: Bazaar Package Importer
  • Author(s): Steve Kowalik
  • Date: 2007-05-10 15:14:19 UTC
  • mfrom: (0.2.2 upstream)
  • Revision ID: james.westby@ubuntu.com-20070510151419-q6sqqtljkt428vph
Tags: 3.0.0-2ubuntu1
* Merge from Debian unstable.
* Remaining Ubuntu changes:
  - Use LSB functions in the init script, and make /var/run/backuppc if
    needed.
  - Remove dependancy on wwwconfig-common.
  - We like apache 2 more, so move it first to the alternatives list.
  - Bump libfile-rsyncp-perl and rsync from Suggests to Depends.
  - Remove stop script symlinks from rc0 and rc6.
* Ubuntu changes dropped:
  - Don't use wwwconfig-common in post{inst,rm}.
* Don't chown /var/run/backuppc in the postinst.
* Don't move /var/lib/backuppc/conf/* (and then delete) to /etc/backuppc
  in rules, upstream is shipping the config files in /etc/backuppc
  themselves.
* Unfuzzify debian/config.pl.diff.
* Munge Maintainer field as per spec.

Show diffs side-by-side

added added

removed removed

Lines of Context:
29
29
#
30
30
#========================================================================
31
31
#
32
 
# Version 2.1.2, released 5 Sep 2005.
 
32
# Version 3.0.0, released 28 Jan 2007.
33
33
#
34
34
# See http://backuppc.sourceforge.net.
35
35
#
42
42
 
43
43
use vars qw( $RsyncLibOK );
44
44
use Carp;
 
45
use Fcntl;
45
46
require Exporter;
46
47
use vars qw( @ISA @EXPORT @EXPORT_OK %EXPORT_TAGS );
47
48
 
100
101
    my($class, $file) = @_;
101
102
    my $data;
102
103
 
103
 
    open(my $fh, "<", $file) || return -1;
 
104
    sysopen(my $fh, $file, O_RDONLY) || return -1;
104
105
    binmode($fh);
105
106
    return -2 if ( sysread($fh, $data, 1) != 1 );
106
107
    close($fh);
107
 
    return $data eq chr(0xd6) ? 1 : 0;
 
108
    return $data eq chr(0xd7) ? 1 : 0;
108
109
}
109
110
 
110
111
#
113
114
# Empty files don't get cached checksums.
114
115
#
115
116
# If verify is set then existing cached checksums are checked.
 
117
# If verify == 2 then only a verify is done; no fixes are applied.
116
118
117
119
# Returns 0 on success.  Returns 1 on good verify and 2 on bad verify.
118
120
# Returns a variety of negative values on error.
119
121
#
120
122
sub digestAdd
121
123
{
122
 
    my($class, $file, $blockSize, $checksumSeed, $verify) = @_;
 
124
    my($class, $file, $blockSize, $checksumSeed, $verify,
 
125
                $protocol_version) = @_;
123
126
    my $retValue = 0;
124
127
 
125
128
    #
138
141
    return -101 if ( !$RsyncLibOK );
139
142
 
140
143
    my $digest = File::RsyncP::Digest->new;
 
144
    $digest->protocol($protocol_version)
 
145
                        if ( defined($protocol_version) );
141
146
    $digest->add(pack("V", $checksumSeed)) if ( $checksumSeed );
142
147
 
143
148
    return -102 if ( !defined(my $fh = BackupPC::FileZIO->open($file, 0, 1)) );
144
149
 
 
150
    my $fileSize;
145
151
    while ( 1 ) {
146
152
        $fh->read(\$data, $nBlks * $blockSize);
 
153
        $fileSize += length($data);
147
154
        last if ( $data eq "" );
148
155
        $blockDigest .= $digest->blockDigest($data, $blockSize, 16,
149
156
                                             $checksumSeed);
164
171
#                                            length($metaData),
165
172
#                                            $file,
166
173
#                                            $eofPosn);
167
 
    open(my $fh2, "+<", $file) || return -103;
 
174
    sysopen(my $fh2, $file, O_RDWR) || return -103;
168
175
    binmode($fh2);
169
176
    return -104 if ( sysread($fh2, $data, 1) != 1 );
170
 
    if ( $data ne chr(0x78) && $data ne chr(0xd6) ) {
 
177
    if ( $data ne chr(0x78) && $data ne chr(0xd6) && $data ne chr(0xd7) ) {
171
178
        &$Log(sprintf("digestAdd: $file has unexpected first char 0x%x",
172
179
                             ord($data)));
173
180
        return -105;
179
186
        #
180
187
        # Verify the cached checksums
181
188
        #
182
 
        return -107 if ( $data ne chr(0xd6) );
 
189
        return -107 if ( $data ne chr(0xd7) );
183
190
        return -108 if ( sysread($fh2, $data3, length($data2) + 1) < 0 );
184
191
        if ( $data2 eq $data3 ) {
185
192
            return 1;
187
194
        #
188
195
        # Checksums don't agree - fall through so we rewrite the data
189
196
        #
190
 
        &$Log("digestAdd: $file verify failed; redoing checksums");
 
197
        &$Log(sprintf("digestAdd: %s verify failed; redoing checksums; len = %d,%d; eofPosn = %d, fileSize = %d",
 
198
                $file, length($data2), length($data3), $eofPosn, $fileSize));
 
199
        #&$Log(sprintf("dataNew  = %s", unpack("H*", $data2)));
 
200
        #&$Log(sprintf("dataFile = %s", unpack("H*", $data3)));
191
201
        return -109 if ( sysseek($fh2, $eofPosn, 0) != $eofPosn );
192
202
        $retValue = 2;
 
203
        return $retValue if ( $verify == 2 );
193
204
    }
194
205
    return -110 if ( syswrite($fh2, $data2) != length($data2) );
195
206
    if ( $verify ) {
205
216
                                sysseek($fh2, 0, 1), $eofPosn + length($data2)));
206
217
                return -112;
207
218
            } else {
208
 
                &$Log(sprintf("digestAdd: $file truncated from %d to %d",
 
219
                &$Log(sprintf("digestAdd: %s truncated from %d to %d",
 
220
                                $file,
209
221
                                sysseek($fh2, 0, 1), $eofPosn + length($data2)));
210
222
            }
211
223
        }
212
224
    }
213
225
    return -113 if ( !defined(sysseek($fh2, 0, 0)) );
214
 
    return -114 if ( syswrite($fh2, chr(0xd6)) != 1 );
 
226
    return -114 if ( syswrite($fh2, chr(0xd7)) != 1 );
215
227
    close($fh2);
216
228
    return $retValue;
217
229
}
235
247
sub digestStart
236
248
{
237
249
    my($class, $fileName, $fileSize, $blockSize, $defBlkSize,
238
 
       $checksumSeed, $needMD4, $compress, $doCache) = @_;
 
250
       $checksumSeed, $needMD4, $compress, $doCache, $protocol_version) = @_;
239
251
 
240
252
    return -1 if ( !$RsyncLibOK );
241
253
 
245
257
        name     => $fileName,
246
258
        needMD4  => $needMD4,
247
259
        digest   => File::RsyncP::Digest->new,
 
260
        protocol_version => $protocol_version,
248
261
    }, $class;
249
262
 
 
263
    $dg->{digest}->protocol($dg->{protocol_version})
 
264
                        if ( defined($dg->{protocol_version}) );
 
265
 
250
266
    if ( $fileSize > 0 && $compress && $doCache >= 0 ) {
251
267
        open(my $fh, "<", $fileName) || return -2;
252
268
        binmode($fh);
253
269
        return -3 if ( read($fh, $data, 1) != 1 );
254
270
        my $ret;
255
271
 
256
 
        if ( $data eq chr(0x78) && $doCache > 0
 
272
        if ( ($data eq chr(0x78) || $data eq chr(0xd6)) && $doCache > 0
257
273
                     && $checksumSeed == RSYNC_CSUMSEED_CACHE ) {
258
274
            #
259
275
            # RSYNC_CSUMSEED_CACHE (32761) is the magic number that
271
287
                            $blockSize
272
288
                                || BackupPC::Xfer::RsyncDigest->blockSize(
273
289
                                                    $fileSize, $defBlkSize),
274
 
                                $checksumSeed);
 
290
                                $checksumSeed, 0, $dg->{protocol_version});
275
291
            if ( $ret < 0 ) {
276
292
                &$Log("digestAdd($fileName) failed ($ret)");
277
293
            }
282
298
            binmode($fh);
283
299
            return -5 if ( read($fh, $data, 1) != 1 );
284
300
        }
285
 
        if ( $ret >= 0 && $data eq chr(0xd6) ) {
 
301
        if ( $ret >= 0 && $data eq chr(0xd7) ) {
286
302
            #
287
303
            # Looks like this file has cached checksums
288
304
            # Read the last 48 bytes: that's 2 file MD4s (32 bytes)
332
348
        return -9 if ( !defined($dg->{fh}) );
333
349
        if ( $needMD4) {
334
350
            $dg->{csumDigest} = File::RsyncP::Digest->new;
 
351
            $dg->{csumDigest}->protocol($dg->{protocol_version})
 
352
                                if ( defined($dg->{protocol_version}) );
335
353
            $dg->{csumDigest}->add(pack("V", $dg->{checksumSeed}));
336
354
        }
337
355
    }
376
394
 
377
395
    if ( $dg->{cached} ) {
378
396
        close($dg->{fh});
379
 
        return $dg->{md4DigestOld} if ( $dg->{needMD4} );
 
397
        if ( $dg->{needMD4} ) {
 
398
            if ( $dg->{protocol_version} <= 26 ) {
 
399
                return $dg->{md4DigestOld};
 
400
            } else {
 
401
                return $dg->{md4Digest};
 
402
            }
 
403
        }
380
404
    } else {
381
405
        #
382
406
        # make sure we read the entire file for the file MD4 digest
421
445
#
422
446
sub logHandlerSet
423
447
{
424
 
    my($sub) = @_;
 
448
    my($dg, $sub) = @_;
425
449
 
426
450
    $Log = $sub;
427
451
}