source: trunk/gsdl/perllib/util.pm@ 14

Last change on this file since 14 was 4, checked in by sjboddie, 26 years ago

Initial revision

  • Property svn:keywords set to Author Date Id Revision
File size: 8.7 KB
Line 
1# various useful utilities
2
3package util;
4
5use File::Copy;
6
7
8# removes files (but not directories)
9sub rm {
10 my (@files) = @_;
11 my @filefiles = ();
12
13 # make sure the files we want to delete exist
14 # and are regular files
15 foreach $file (@files) {
16 if (!-e $file) {
17 print STDERR "util::rm $file does not exist\n";
18 } elsif (!-f $file) {
19 print STDERR "util::rm $file is not a regular file\n";
20 } else {
21 push (@filefiles, $file);
22 }
23 }
24
25 # remove the files
26 my $numremoved = unlink @filefiles;
27
28 # check to make sure all of them were removed
29 if ($numremoved != scalar(@filefiles)) {
30 print STDERR "util::rm Not all files were removed\n";
31 }
32}
33
34
35# recursive removal
36sub rm_r {
37 my (@files) = @_;
38
39 # recursively remove the files
40 foreach $file (@files) {
41 $file =~ s/[\/\\]+$//; # remove trailing slashes
42
43 if (!-e $file) {
44 print STDERR "util::rm_r $file does not exist\n";
45
46 } elsif (-d $file) {
47 # get the contents of this directory
48 if (!opendir (INDIR, $file)) {
49 print STDERR "util::rm_r could not open directory $file\n";
50 } else {
51 my @filedir = grep (!/^\.\.?$/, readdir (INDIR));
52 closedir (INDIR);
53
54 # remove all the files in this directory
55 &rm_r (map {$_="$file/$_";} @filedir);
56
57 # remove this directory
58 if (!rmdir $file) {
59 print STDERR "util::rm_r couldn't remove directory $file\n";
60 }
61 }
62
63 } else {
64 # remove this file
65 &rm ($file);
66 }
67 }
68}
69
70
71# copies a file or a group of files
72sub cp {
73 my $dest = pop (@_);
74 my (@srcfiles) = @_;
75
76 # remove trailing slashes from source and destination files
77 $dest =~ s/[\\\/]+$//;
78 map {$_ =~ s/[\\\/]+$//;} @srcfiles;
79
80 # a few sanity checks
81 if (scalar (@srcfiles) == 0) {
82 print STDERR "util::cp no destination directory given\n";
83 return;
84 } elsif ((scalar (@srcfiles) > 1) && (!-d $dest)) {
85 print STDERR "util::cp if multiple source files are given the ".
86 "destination must be a directory\n";
87 return;
88 }
89
90 # copy the files
91 foreach $file (@srcfiles) {
92 my $tempdest = $dest;
93 if (-d $tempdest) {
94 my ($filename) = $file =~ /([^\\\/]+)$/;
95 $tempdest .= "/$filename";
96 }
97 if (!-e $file) {
98 print STDERR "util::cp $file does not exist\n";
99 } elsif (!-f $file) {
100 print STDERR "util::cp $file is not a plain file\n";
101 } else {
102 &File::Copy::copy ($file, $tempdest);
103 }
104 }
105}
106
107
108# recursively copies a file or group of files
109# syntax: cp_r (sourcefiles, destination file or directory)
110sub cp_r {
111 my $dest = pop (@_);
112 my (@srcfiles) = @_;
113
114 # remove trailing slashes from source and destination files
115 $dest =~ s/[\\\/]+$//;
116 map {$_ =~ s/[\\\/]+$//;} @srcfiles;
117
118 # a few sanity checks
119 if (scalar (@srcfiles) == 0) {
120 print STDERR "util::cp no destination directory given\n";
121 return;
122 } elsif ((scalar (@srcfiles) > 1) && (!-d $dest)) {
123 print STDERR "util::cp if multiple source files are given the ".
124 "destination must be a directory\n";
125 return;
126 }
127
128 # copy the files
129 foreach $file (@srcfiles) {
130 # copy the file to within dest if dest is a directory
131 # exception: if there is only one source file and that
132 # source file is a directory
133 my $tempdest = $dest;
134 if (-d $tempdest && !(scalar(@srcfiles) == 1 && -d $file)) {
135 my ($filename) = $file =~ /([^\\\/]+)$/;
136 $tempdest .= "/$filename";
137 }
138
139 if (!-e $file) {
140 print STDERR "util::cp $file does not exist\n";
141
142 } elsif (-d $file) {
143 # make a new directory (if needed)
144 mkdir ($tempdest, 0775) unless -e $tempdest;
145
146 # get the contents of this directory
147 if (!opendir (INDIR, $file)) {
148 print STDERR "util::cp_r could not open directory $file\n";
149 } else {
150 my @filedir = grep (!/^\.\.?$/, readdir (INDIR));
151 closedir (INDIR);
152
153 # copy all the files in this directory
154 &cp_r (map {$_="$file/$_";} @filedir, $tempdest);
155 }
156
157 } else {
158 &cp($file, $tempdest);
159 }
160 }
161}
162
163
164sub mk_all_dir {
165 my ($dir) = @_;
166
167 # use / for the directory separator, remove duplicate and
168 # trailing slashes
169 $dir=~s/[\\\/]+/\//g;
170 $dir=~s/[\\\/]+$//;
171
172 # make sure the cache directory exists
173 my $dirsofar = "";
174 my $first = 1;
175 foreach $dirname (split ("/", $dir)) {
176 $dirsofar .= "/" unless $first;
177 $first = 0;
178
179 $dirsofar .= $dirname;
180
181 next if $dirname =~ /^(|[a-z]:)$/i;
182 if (!-e $dirsofar && !mkdir ($dirsofar, 0775)) {
183 print STDERR "util::mk_all_dir could not create directory $dirsofar\n";
184 return;
185 }
186 }
187}
188
189
190# updates a copy of a directory in some other part of the filesystem
191# verbosity settings are: 0=low, 1=normal, 2=high
192# both $fromdir and $todir should be absolute paths
193sub cachedir {
194 my ($fromdir, $todir, $verbosity) = @_;
195 $verbosity = 1 unless defined $verbosity;
196
197 # use / for the directory separator, remove duplicate and
198 # trailing slashes
199 $fromdir=~s/[\\\/]+/\//g;
200 $fromdir=~s/[\\\/]+$//;
201 $todir=~s/[\\\/]+/\//g;
202 $todir=~s/[\\\/]+$//;
203
204 &mk_all_dir ($todir);
205
206 # get the directories in ascending order
207 if (!opendir (FROMDIR, $fromdir)) {
208 print STDERR "util::cachedir could not read directory $fromdir\n";
209 return;
210 }
211 my @fromdir = grep (!/^\.\.?$/, sort(readdir (FROMDIR)));
212 closedir (FROMDIR);
213
214 if (!opendir (TODIR, $todir)) {
215 print STDERR "util::cacedir could not read directory $todir\n";
216 return;
217 }
218 my @todir = grep (!/^\.\.?$/, sort(readdir (TODIR)));
219 closedir (TODIR);
220
221 my $fromi = 0;
222 my $toi = 0;
223
224 while ($fromi < scalar(@fromdir) || $toi < scalar(@todir)) {
225# print "fromi: $fromi toi: $toi\n";
226
227 # see if we should delete a file/directory
228 # this should happen if the file/directory
229 # is not in the from list or if its a different
230 # size, or has an older timestamp
231 if ($toi < scalar(@todir)) {
232 if (($fromi >= scalar(@fromdir)) ||
233 ($todir[$toi] lt $fromdir[$fromi] ||
234 ($todir[$toi] eq $fromdir[$fromi] &&
235 &differentfiles("$fromdir/$fromdir[$fromi]","$todir/$todir[$toi]",
236 $verbosity)))) {
237
238 # the files are different
239 &rm_r("$todir/$todir[$toi]");
240 splice(@todir, $toi, 1); # $toi stays the same
241
242 } elsif ($todir[$toi] eq $fromdir[$fromi]) {
243 # the files are the same
244 # if it is a directory, check its contents
245 if (-d "$todir/$todir[$toi]") {
246 &cachedir ("$fromdir/$fromdir[$fromi]",
247 "$todir/$todir[$toi]", $verbosity);
248 }
249
250 $toi++;
251 $fromi++;
252 next;
253 }
254 }
255
256 # see if we should insert a file/directory
257 # we should insert a file/directory if there
258 # is no tofiles left or if the tofile does not exist
259 if ($fromi < scalar(@fromdir) && ($toi >= scalar(@todir) ||
260 $todir[$toi] gt $fromdir[$fromi])) {
261 &cp_r ("$fromdir/$fromdir[$fromi]", "$todir/$fromdir[$fromi]");
262 splice (@todir, $toi, 0, $fromdir[$fromi]);
263
264 $toi++;
265 $fromi++;
266 }
267 }
268}
269
270# this function returns -1 if either file is not found
271# assumes that $file1 and $file2 are absolute file names or
272# in the current directory
273# $file2 is allowed to be newer than $file1
274sub differentfiles {
275 my ($file1, $file2, $verbosity) = @_;
276 $verbosity = 1 unless defined $verbosity;
277
278 $file1 =~ s/\/+$//;
279 $file2 =~ s/\/+$//;
280
281 my ($file1name) = $file1 =~ /\/([^\/]*)$/;
282 my ($file2name) = $file2 =~ /\/([^\/]*)$/;
283
284 return -1 unless (-e $file1 && -e $file2);
285 if ($file1name ne $file2name) {
286 print STDERR "filenames are not the same\n" if ($verbosity >= 2);
287 return 1;
288 }
289
290 @file1stat = stat ($file1);
291 @file2stat = stat ($file2);
292
293 if (-d $file1) {
294 if (! -d $file2) {
295 print STDERR "one file is a directory\n" if ($verbosity >= 2);
296 return 1;
297 }
298 return 0;
299 }
300
301 # both must be regular files
302 unless (-f $file1 && -f $file2) {
303 print STDERR "one file is not a regular file\n" if ($verbosity >= 2);
304 return 1;
305 }
306
307 # the size of the files must be the same
308 if ($file1stat[7] != $file2stat[7]) {
309 print STDERR "different sized files\n" if ($verbosity >= 2);
310 return 1;
311 }
312
313 # the second file cannot be older than the first
314 if ($file1stat[9] > $file2stat[9]) {
315 print STDERR "file is older\n" if ($verbosity >= 2);
316 return 1;
317 }
318
319 return 0;
320}
321
322
323sub get_tmp_filename {
324 my $tmpdir = "$ENV{'GSDLHOME'}/tmp";
325 &mk_all_dir ($tmpdir) unless -e $tmpdir;
326
327 my $count = 1000;
328 my $rand = int(rand $count);
329 while (-e "$tmpdir/F$rand") {
330 $rand = int(rand $count);
331 $count++;
332 }
333
334 return "$tmpdir/F$rand";
335}
336
337
338sub filename_cat {
339 my (@filenames) = @_;
340 my $filename = join("/", @filenames);
341
342 # remove duplicate slashes and remove the last slash
343 $filename =~ s/[\\\/]+/\//g;
344 $filename =~ s/\/$//;
345
346 return $filename;
347}
348
349
350# if this is running on windows we want binaries to end in
351# .exe, otherwise they don't have to end in any extension
352sub get_os_exe {
353 return ".exe" if $ENV{'GSDLOS'} =~ /^windows$/i;
354 return "";
355}
356
357
358
3591;
Note: See TracBrowser for help on using the repository browser.