--- syncmail/syncmail 2001/10/27 23:53:49 1.3 +++ syncmail/syncmail 2001/10/28 03:51:24 1.4 @@ -8,8 +8,9 @@ use Coro::Signal; use Coro::RWLock; +use Set::Scalar; + use Fcntl; -use MD5; use constant PROTVERSION => 1; @@ -82,8 +83,6 @@ my $vc = new vc; my $folder = new folder name => $name; - #my ($rfid, $rmtime) = split /\s+/, (request open => $name)->[1]; - ::give; $vc->snd("open", $name); $vc->snd("mtime"); @@ -91,14 +90,43 @@ $folder->check; $folder->read_mdif; - my $mtime = $folder->{host}{$OTHERNAME}; + my $ctime = $folder->{host}{$OTHERNAME} || -1; my $rtime = $vc->rcv; - $vc->snd("diff", $rtime); - $folder->{host}{$OTHERNAME} = $folder->{mtime}; + $vc->snd("diff", $ctime); + + my (%ladd, %ldel, %radd, %rdel); + + my @diff = grep { $_->[0] > $ctime } @{$folder->{diff}}; + $diff = $vc->rcv; + + while () { + if ($diff >= 0 and (!@diff or $diff <= $diff[0][0])) { + my @add = split /\0/, $vc->rcv; + my @del = split /\0/, $vc->rcv; + $diff = $vc->rcv; + slog 0, "applying remote diff $diff\n"; + for (@del) { undef $rdel{$_}; delete $radd{$_}; delete $ladd{$_}; } + for (@add) { undef $radd{$_}; delete $rdel{$_}; delete $ldel{$_}; } + } elsif (@diff) { + slog 0, "applying local diff $diff[0][0]\n"; + for (@{$diff[0][2]}) { undef $rdel{$_}; delete $radd{$_}; delete $ladd{$_}; } + for (@{$diff[0][1]}) { undef $radd{$_}; delete $rdel{$_}; delete $ldel{$_}; } + shift @diff; + } else { + slog 0, "no more diffing\n"; + last; + } + } + + slog 0, "LADD ".join(" ", keys %ladd)."\n"; + slog 0, "LDEL ".join(" ", keys %ldel)."\n"; + slog 0, "RADD ".join(" ", keys %radd)."\n"; + slog 0, "RDEL ".join(" ", keys %rdel)."\n"; + + #$folder->{host}{$OTHERNAME} = time; + #$vc->snd("setctime", time); - #request "update $rfid $folder->{mtime}"; - #request "close $rfid"; undef $quit_guard; } } @@ -153,12 +181,18 @@ while (my $msg = $vc->rcv) { if ($msg eq "mtime") { $vc->snd($folder->{mtime}); - } elsif ($msg =~ /^update (\d+) (\d+)$/) { - #if ($folder[$1]->{host}{$OTHERNAME} != $2) { - # $folder[$1]->{host}{$OTHERNAME} = $2; - # $folder[$1]->dirty; - #} - #reply $id, 200, "ok"; + } elsif ($msg eq "diff") { + my $time = $vc->rcv; + for (@{$folder->{diff}}) { + next if $_->[0] <= $time; + $vc->snd($_->[0], + (join "\0", @{$_->[1]}), + (join "\0", @{$_->[2]}), + ); + } + $vc->snd(-1); + } elsif ($msg eq "setctime") { + $folder->{host}{$OTHERNAME} = $vc->rcv; } else { die "protocol error, unknown folder command ($msg)\n"; }