Commit | Line | Data |
---|---|---|
5d6d95a3 JB |
1 | #!/usr/bin/perl |
2 | # | |
3 | # /etc/ports/drivers/rsync: rsync(1) driver script for ports(8) | |
4 | # | |
5 | ||
6 | use warnings; | |
7 | use strict; | |
8 | use File::Basename; | |
9 | ||
10 | my $host = ''; | |
11 | my $collection = ''; | |
12 | my $destination = ''; | |
13 | my %new_checkouts; | |
14 | my %old_checkouts; | |
15 | ||
16 | sub error | |
17 | { | |
18 | my $message = shift; | |
19 | print "Error: $message ($!)\nUpdating failed\n"; | |
20 | exit 1; | |
21 | } | |
22 | ||
23 | sub warning | |
24 | { | |
25 | my $message = shift; | |
26 | print "Warning: $message ($!)\n"; | |
27 | } | |
28 | ||
29 | if ($#ARGV < 0) | |
30 | { | |
31 | print "Usage: $0 <file>\n"; | |
32 | exit 1; | |
33 | } | |
34 | ||
35 | open(FILE, $ARGV[0]) or error("Couldn't open $ARGV[0]"); | |
36 | while (<FILE>) | |
37 | { | |
38 | chomp; | |
39 | if (/^host=(.*)/) { $host = $1; } | |
40 | elsif (/^collection=(.*)/) { $collection = $1; } | |
41 | elsif (/^destination=(.*)/) { $destination = $1; } | |
42 | } | |
43 | close(FILE); | |
44 | ||
45 | if ($host eq '') { error("Host field not set in $ARGV[0]"); } | |
46 | if ($collection eq '') { error("Collection field not set in $ARGV[0]"); } | |
47 | if ($destination eq '') { error("Destination field not set in $ARGV[0]"); } | |
48 | ||
49 | if (-e "$destination/.checkouts") | |
50 | { | |
51 | # read the old .checkouts file into memory | |
52 | open(FILE, "$destination/.checkouts") or error("Couldn't read checkouts from $destination/.checkouts"); | |
53 | while (<FILE>) | |
54 | { | |
55 | chomp; | |
56 | $old_checkouts{$_} = 1; | |
57 | } | |
58 | close(FILE); | |
59 | } | |
60 | ||
61 | print "Updating file list from " . $host . "::$collection\n"; | |
62 | ||
63 | # get the remote file list (new .checkouts) | |
64 | open(PIPE, 'rsync -crz ' . $host . '::' . $collection . '|') or error("Couldn't open pipe to rsync"); | |
65 | while (<PIPE>) | |
66 | { | |
67 | chomp; | |
68 | ||
69 | next if /^MOTD:/; # ignore MOTD lines | |
70 | s/^(.{43})//; # ignore the first 43 characters (mode, date etc...) | |
71 | next if /^.$/; # ignore the . directory | |
72 | ||
73 | $new_checkouts{$_} = 1; | |
74 | } | |
75 | close(PIPE); | |
76 | error("Running rsync failed") unless $? == 0; | |
77 | ||
78 | print "Updating collection " . basename($destination) . "\n"; | |
79 | ||
80 | # now really run rsync | |
81 | open(PIPE, 'rsync -crz --log-format "%o %n" ' . $host . "::$collection $destination|") or error("Couldn't open pipe to rsync"); | |
82 | while (<PIPE>) | |
83 | { | |
84 | chomp; | |
85 | ||
86 | if (/^recv (.*)/) | |
87 | { | |
88 | if ($old_checkouts{$1}) | |
89 | { | |
90 | s/^recv/ Edit/; | |
91 | } | |
92 | else | |
93 | { | |
94 | s/^recv/ Checkout/; | |
95 | } | |
96 | } | |
97 | ||
98 | print $_ . "\n"; | |
99 | } | |
100 | close(PIPE); | |
101 | error("Running rsync failed") unless $? == 0; | |
102 | ||
103 | # save new checkouts into .checkouts | |
104 | open(FILE, ">$destination/.checkouts") or error("Couldn't save checkouts to $destination/.checkouts"); | |
105 | foreach my $checkout (sort keys %new_checkouts) | |
106 | { | |
107 | print FILE "$checkout\n"; | |
108 | } | |
109 | close(FILE); | |
110 | ||
111 | # use chroot as an additional safety measure when removing files | |
112 | chroot($destination) or error("Couldn't chroot into $destination"); | |
113 | chdir('/'); | |
114 | ||
115 | # iterate through old checkouts, remove obsolete files | |
116 | foreach my $checkout (sort keys %old_checkouts) | |
117 | { | |
118 | if (!$new_checkouts{$checkout}) | |
119 | { | |
120 | if (-f $checkout) | |
121 | { | |
122 | print " Delete $checkout\n"; | |
123 | unlink($checkout) or warning("Couldn't delete $checkout"); | |
124 | } | |
125 | } | |
126 | } | |
127 | ||
128 | # iterate through old checkouts, remove obsolete directories | |
129 | foreach my $checkout (sort keys %old_checkouts) | |
130 | { | |
131 | if (!$new_checkouts{$checkout}) | |
132 | { | |
133 | if (-d $checkout) | |
134 | { | |
135 | print " Delete $checkout\n"; | |
136 | rmdir($checkout) or warning("Couldn't delete $checkout"); | |
137 | } | |
138 | } | |
139 | } | |
140 | ||
141 | print "Finished successfully\n"; | |
142 | ||
143 | # End of file |