~ubuntu-branches/ubuntu/vivid/cctools/vivid

« back to all changes in this revision

Viewing changes to parrot/src/make_growfs

  • Committer: Bazaar Package Importer
  • Author(s): Michael Hanke
  • Date: 2011-05-07 09:05:00 UTC
  • Revision ID: james.westby@ubuntu.com-20110507090500-lqpmdtwndor6e7os
Tags: upstream-3.3.2
ImportĀ upstreamĀ versionĀ 3.3.2

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#!/usr/bin/perl -w
 
2
 
 
3
# make_growfs
 
4
#
 
5
# This script simply traverses a directory structure and
 
6
# creates a file named .growfsdir that lists all the files
 
7
# in the directory structure recursively.  
 
8
# The Parrot growfs module uses this information in order to 
 
9
# make a web server look like a filesystem.
 
10
 
11
# Example use:
 
12
#    make_growfs /home/fred/www
 
13
#    parrot_run tcsh
 
14
#    cd /growfs/my.web.server/~fred
 
15
#    ls -la
 
16
 
 
17
use Fcntl ":mode";
 
18
 
 
19
$verbose_mode = 0;
 
20
$verbose_changes = 1;
 
21
$follow_mode = "a";
 
22
$checksum_mode = 1;
 
23
 
 
24
$total_dirs = 0;
 
25
$total_files = 0;
 
26
$total_links = 0;
 
27
$total_checksums = 0;
 
28
 
 
29
$name = 0;
 
30
$GROW_EPOCH = 1199163600;
 
31
 
 
32
sub load_cache
 
33
{
 
34
        my $dirpath = shift;
 
35
        my $type;
 
36
        my $name;
 
37
        my $mode;
 
38
        my $size;
 
39
        my $mtime;
 
40
        my $checksum;
 
41
 
 
42
        while(<DIRFILE>) {
 
43
                ($type,$name,$mode,$size,$mtime,$checksum) = split;
 
44
                if($type eq "D") {
 
45
                        load_cache("$dirpath/$name");
 
46
                } elsif($type eq "E") {
 
47
                        return;
 
48
                } else {
 
49
                        $mtime_cache{"$dirpath/$name"} = "$mtime";
 
50
                        $size_cache{"$dirpath/$name"} = "$size";
 
51
                        $checksum_cache{"$dirpath/$name"} = "$checksum";
 
52
                }
 
53
                return if(!defined DIRFILE);
 
54
        }
 
55
 
 
56
}
 
57
 
 
58
sub reorder_stat
 
59
{
 
60
        my ($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,$atime,$mtime,$ctime,$blksize,$blocks) = @_;
 
61
        return ($mode,$size,$mtime-$GROW_EPOCH);
 
62
}
 
63
 
 
64
sub listdir
 
65
{
 
66
        my $dirname = shift;
 
67
        my $dir;
 
68
        my $d;
 
69
        my $subdirname;
 
70
 
 
71
        opendir $dir, $dirname or die "make_growfs: couldn't open $dirname\n";
 
72
 
 
73
        while( $d = readdir($dir) ) {
 
74
 
 
75
                if( $d =~ ".growfs.*") {
 
76
                        next;
 
77
                }
 
78
 
 
79
                if( $d eq "." || $d eq ".." ) {
 
80
                        next;
 
81
                }
 
82
 
 
83
                $subdirname = "$dirname/$d";
 
84
 
 
85
                print "$subdirname\n" if($verbose_mode);
 
86
 
 
87
                if($follow_mode eq "y") {
 
88
                        # if we are following symbolic links, then
 
89
                        # stat the item the link points to.
 
90
                        @info = stat $subdirname;
 
91
 
 
92
                        # but if that fails, it could be a broken link,
 
93
                        # so try to get that instead.
 
94
                        if(!@info) {
 
95
                                @info = lstat $subdirname;
 
96
                                if(@info) {
 
97
                                        print STDERR "make_growfs: broken symbolic link $subdirname\n";
 
98
                                }
 
99
                        }
 
100
                } else {
 
101
                        # if we are not following symbolic links,
 
102
                        # then look at the link itself and report that
 
103
                        @info = lstat $subdirname;
 
104
                }
 
105
 
 
106
                retry_link:
 
107
 
 
108
                if(!@info) {
 
109
                        print STDERR "make_growfs: couldn't access $subdirname\n";
 
110
                        next;
 
111
                }
 
112
 
 
113
                @info = reorder_stat @info;
 
114
 
 
115
                if( S_ISLNK($info[0]) ) {
 
116
                        $linkname = readlink "$subdirname";
 
117
                        if(substr($linkname,0,1) eq "/") {
 
118
                                $toplength = length $topdir;
 
119
                                if(substr($linkname,0,$toplength) eq $topdir) {
 
120
                                        $linkname = substr($linkname,$toplength);
 
121
                                        if(substr($linkname,0,1) ne "/") {
 
122
                                                $linkname = "/" . $linkname;
 
123
                                        }
 
124
                                } else {
 
125
                                        if( $follow_mode eq "a" ) {
 
126
                                                print STDERR "make_growfs: following link $subdirname to $linkname\n";
 
127
                                                @info = stat $subdirname;
 
128
                                                goto retry_link;
 
129
                                        } else {
 
130
                                                print STDERR "make_growfs: symbolic link $subdirname points to $linkname outside the root $topdir\n";
 
131
                                        }
 
132
                                }
 
133
                        }
 
134
                        print DIRFILE "L $d\t@info 0 $linkname\n";
 
135
                        $total_links++;
 
136
                } elsif( S_ISDIR($info[0]) ) {
 
137
                        print DIRFILE "D $d\t@info 0\n";
 
138
                        listdir($subdirname);
 
139
                        print DIRFILE "E\n";
 
140
                        $total_dirs++;
 
141
                } else {
 
142
                        if($checksum_mode) {
 
143
                                $mtime = $mtime_cache{$subdirname};
 
144
                                $size = $size_cache{$subdirname};
 
145
                                if(defined $mtime && $mtime==$info[2] && defined $size && $size==$info[1]) {
 
146
                                        $checksum = $checksum_cache{$subdirname};
 
147
                                } else {
 
148
                                        ($checksum,$name) = split " ", `sha1sum \"$subdirname\"`;
 
149
                                        $total_checksums++;
 
150
                                        print "$subdirname changed: $checksum\n" if($verbose_mode || $verbose_changes);
 
151
                                }
 
152
                        } else {
 
153
                                $checksum = 0;
 
154
                        }
 
155
                        print DIRFILE "F $d\t@info $checksum\n";
 
156
                        $total_files++;
 
157
                }
 
158
        }
 
159
        closedir $dir;
 
160
}
 
161
 
 
162
sub show_help
 
163
{
 
164
print "Use: $0 [options] <directory>
 
165
Where options are:
 
166
  -v  Give verbose messages.
 
167
  -K  Create checksums for files. (default)
 
168
  -k  Disable checksums for files.
 
169
  -f  Follow all symbolic links.
 
170
  -F  Do not follow any symbolic links.
 
171
  -a  Only follow links that fall outside the root.  (default)
 
172
  -h  Show this help file.
 
173
";
 
174
}
 
175
 
 
176
while( defined $ARGV[0] ) {
 
177
        $arg = $ARGV[0];
 
178
        if( $arg eq "-f" ) {
 
179
                $follow_mode = "y";
 
180
        } elsif( $arg eq "-F" ) {
 
181
                $follow_mode = "n";
 
182
        } elsif( $arg eq "-a" ) {
 
183
                $follow_mode = "a";
 
184
        } elsif( $arg eq "-v" ) {
 
185
                $verbose_mode = 1;
 
186
        } elsif( $arg eq "-c" ) {
 
187
                $verbose_changes = 1;
 
188
        } elsif( $arg eq "-k" ) {
 
189
                $checksum_mode = 0;
 
190
        } elsif( $arg eq "-K" ) {
 
191
                $checksum_mode = 1;
 
192
        } elsif( $arg eq "-h" ) {
 
193
                show_help();
 
194
                exit(0);
 
195
        } elsif( $arg =~ "-.*" ) {
 
196
                print "make_growfs: unknown argion: $arg (-h for help)\n";
 
197
                exit(0);
 
198
        } else {
 
199
                $topdir = $arg;
 
200
        }
 
201
        shift @ARGV;
 
202
}
 
203
 
 
204
if(!defined $topdir) {
 
205
        print "make_growfs: please give me a directory name (-h for help)\n";
 
206
        exit(0);
 
207
}
 
208
 
 
209
$dirfile = "$topdir/.growfsdir";
 
210
 
 
211
print "make_growfs: loading existing directory from $dirfile\n";
 
212
 
 
213
if(open DIRFILE, "$topdir/.growfsdir") {
 
214
        <DIRFILE>;
 
215
        load_cache($topdir);
 
216
        close(DIRFILE);
 
217
} else {
 
218
        print "make_growfs: no directory exists, this might be quite slow...\n";
 
219
}
 
220
 
 
221
print "make_growfs: scanning directory tree for changes...\n";
 
222
 
 
223
open DIRFILE, ">$topdir/.growfsdirtmp" or die "make_growfs: cannot write to directory file $topdir/.growfsdirtmp\n";
 
224
@info = reorder_stat stat $topdir;
 
225
print DIRFILE "D root\t@info 0\n";
 
226
 
 
227
listdir "$topdir";
 
228
 
 
229
print DIRFILE "E\n";
 
230
close DIRFILE;
 
231
 
 
232
rename "$topdir/.growfsdirtmp", "$topdir/.growfsdir";
 
233
system "sha1sum < $topdir/.growfsdir > $topdir/.growfschecksum";
 
234
 
 
235
printf "make_growfs: $total_files files, $total_links links, $total_dirs dirs, $total_checksums checksums computed\n";
 
236
exit 0;