ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/syncmail/syncmail
(Generate patch)

Comparing syncmail/syncmail (file contents):
Revision 1.3 by root, Sat Oct 27 23:53:49 2001 UTC vs.
Revision 1.6 by root, Sun Oct 28 20:52:25 2001 UTC

6use Coro::Semaphore; 6use Coro::Semaphore;
7use Coro::Channel; 7use Coro::Channel;
8use Coro::Signal; 8use Coro::Signal;
9use Coro::RWLock; 9use Coro::RWLock;
10 10
11use Set::Scalar;
12
11use Fcntl; 13use Fcntl;
12use MD5;
13 14
14use constant PROTVERSION => 1;
15
16$VERSION = 0.1; 15our $VERSION = 0.1;
16
17our $NOW = time;
17 18
18require "config.pl"; 19require "config.pl";
19 20
20use folder; 21use folder;
21use vc; 22use vc;
62 opendir my $dh, $PREFIX 63 opendir my $dh, $PREFIX
63 or die "$PREFIX: $!"; 64 or die "$PREFIX: $!";
64 65
65 while (defined (my $folder = readdir $dh)) { 66 while (defined (my $folder = readdir $dh)) {
66 next if $folder =~ /^\./; 67 next if $folder =~ /^\./;
68 next if $folder =~ /~$/;
67 next unless -f "$PREFIX/$folder"; 69 next unless -f "$PREFIX/$folder";
68 push @folders, $folder; 70 push @folders, $folder;
69 } 71 }
70 72
71 @folders; 73 @folders;
77 my $name = $_[0]; 79 my $name = $_[0];
78 80
79 my $quit_guard = quit_guard; 81 my $quit_guard = quit_guard;
80 async { 82 async {
81 my $guard = $sync_folder->guard; 83 my $guard = $sync_folder->guard;
82 my $vc = new vc; 84 my $vc = create vc;
83 85
84 my $folder = new folder name => $name; 86 my $folder = new folder name => $name;
85 #my ($rfid, $rmtime) = split /\s+/, (request open => $name)->[1];
86 ::give;
87 87
88 $vc->snd("open", $name); 88 $vc->snd("open", $name);
89 $vc->snd("mtime"); 89 $vc->snd("mtime");
90 90
91 $folder->check; 91 $folder->check;
92 $folder->read_mdif; 92 $folder->read_mdif;
93 93
94 my $mtime = $folder->{host}{$OTHERNAME}; 94 my $ctime = $folder->{host}{$OTHERNAME} || -1;
95 my $rtime = $vc->rcv; 95 my $rtime = $vc->rcv;
96 96
97 $vc->snd("diff", $rtime); 97 $vc->snd("diff", $ctime);
98
99 my %diff; #
100 # 00 - local del
101 # 01 - local add
102 # 10 - remote del
103 # 11 - remote add
104
105 my @diff = grep { $_->[0] > $ctime } @{$folder->{diff}};
106 $diff = $vc->rcv;
107
108 while () {
109 if ($diff >= 0 and (!@diff or $diff <= $diff[0][0])) {
110 slog 0, "applying remote diff $diff (@add, @del)\n";
111 $diff{$_} = 0b01 for split /\0/, $vc->rcv; # add
112 $diff{$_} = 0b00 for split /\0/, $vc->rcv; # del
113
114 $diff = $vc->rcv;
115 } elsif (@diff) {
116 slog 0, "applying local diff $diff[0][0]\n";
117 $diff{$_} = 0b11 for @{$diff[0][1]};
118 $diff{$_} = 0b10 for @{$diff[0][2]};
119
120 shift @diff;
121 } else {
122 slog 0, "no more diffing\n";
123 last;
124 }
125 }
126
127 # append or update, depending on wether there are messages to be deleted
128 $vc->snd("begin");
129 $folder->begin_update;
130
131 while (my ($k,$v) = each %diff) {
132 push @{$diff[$v]}, $k;
133 slog 0, "DIFF $k : $v\n";#d#
134 }
135
136 $vc->snd("delete", join "\0", @{$diff[2]});
137 $folder->delete(@{$diff[0]});
138
139 $vc->snd("end");
140 $folder->end_update;
141
142 $vc->snd("ctime", $folder->{ctime});
98 $folder->{host}{$OTHERNAME} = $folder->{mtime}; 143 $folder->{host}{$OTHERNAME} = $vc->rcv;
99 144
100 #request "update $rfid $folder->{mtime}"; 145 # sanity check
101 #request "close $rfid"; 146 $vc->snd("inventory");
147 if ($folder->inventory ne $vc->rcv) {
148 slog 0, "FATAL: folder inventory mismatch after update";
149 die;
150 }
151 slog 0, "LINV ".$folder->inventory."\n";
152 slog 0, "RINV ".$vc->rcv."\n";
153
102 undef $quit_guard; 154 undef $quit_guard;
103 } 155 }
104} 156}
105 157
106sub main { 158sub main {
107 my $vc = new vc; 159 my $vc = create vc;
108 160
109 # time checking done symmetrically 161 # time checking done symmetrically
110 { 162 {
111 my $time = time; 163 my $time = time;
112 $vc->snd("time"); 164 $vc->snd("time");
114 abs (($time + time)*0.5 - $othertime) <= $::MAXTIMEDIFF 166 abs (($time + time)*0.5 - $othertime) <= $::MAXTIMEDIFF
115 or die "ERROR: time difference between hosts larger than $::MAXTIMEDIFF"; 167 or die "ERROR: time difference between hosts larger than $::MAXTIMEDIFF";
116 } 168 }
117#Coro::Event::do_timer(after => 60);#d# 169#Coro::Event::do_timer(after => 60);#d#
118 170
119 $vc->snd("name"); 171 $vc->snd("setname", $MYNAME); $OTHERNAME = $vc->rcv;
120 $OTHERNAME = $vc->rcv;
121 172
122 if ($SLAVE) { 173 if ($SLAVE) {
123 # 174 #
124 } else { 175 } else {
125 $vc->snd("list"); 176 $vc->snd("list");
151 $folder->read_mdif; 202 $folder->read_mdif;
152 203
153 while (my $msg = $vc->rcv) { 204 while (my $msg = $vc->rcv) {
154 if ($msg eq "mtime") { 205 if ($msg eq "mtime") {
155 $vc->snd($folder->{mtime}); 206 $vc->snd($folder->{mtime});
156 } elsif ($msg =~ /^update (\d+) (\d+)$/) { 207 } elsif ($msg eq "inventory") {
157 #if ($folder[$1]->{host}{$OTHERNAME} != $2) { 208 $vc->snd($folder->inventory);
158 # $folder[$1]->{host}{$OTHERNAME} = $2; 209 } elsif ($msg eq "diff") {
159 # $folder[$1]->dirty; 210 my $time = $vc->rcv;
211 for (@{$folder->{diff}}) {
212 next if $_->[0] <= $time;
213 $vc->snd($_->[0],
214 (join "\0", @{$_->[1]}),
215 (join "\0", @{$_->[2]}),
216 );
160 #} 217 }
161 #reply $id, 200, "ok"; 218 $vc->snd(-1);
219 } elsif ($msg eq "begin") {
220 $folder->begin_update;
221 } elsif ($msg eq "end") {
222 $folder->end_update;
223 } elsif ($msg eq "mtime") {
224 $vc->snd($folder->{mtime});
225 } elsif ($msg eq "setctime") {
226 $folder->{host}{$OTHERNAME} = $vc->rcv;
162 } else { 227 } else {
163 die "protocol error, unknown folder command ($msg)\n"; 228 die "protocol error, unknown folder command ($msg)\n";
164 } 229 }
165 } 230 }
166} 231}
169 my $vc = shift; 234 my $vc = shift;
170 235
171 slog 8, "new connection $vc->{port}\n"; 236 slog 8, "new connection $vc->{port}\n";
172 237
173 while (my $msg = $vc->rcv) { 238 while (my $msg = $vc->rcv) {
174 if ($msg eq "name") { 239 if ($msg eq "setname") {
175 $vc->snd($::MYNAME); 240 $vc->snd($MYNAME);
241 $OTHERNAME = $vc->rcv;
176 } elsif ($msg eq "pri") { 242 } elsif ($msg eq "pri") {
177 $self->{pri} = $vc->rcv; 243 $vc->{pri} = $vc->rcv;
178 } elsif ($msg eq "time") { 244 } elsif ($msg eq "time") {
179 $vc->snd(time); 245 $vc->snd(time);
180 } elsif ($msg eq "list") { 246 } elsif ($msg eq "list") {
181 $vc->snd(join "\0", find_folders); 247 $vc->snd(join "\0", find_folders);
182 } elsif ($msg eq "open") { 248 } elsif ($msg eq "open") {

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines