root/juggler/trunk/release/scripts/InstallOps.pm

Revision 20974, 10.3 kB (checked in by patrick, 1 year ago)

Copyright update.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1 # ************** <auto-copyright.pl BEGIN do not edit this line> **************
2 #
3 # VR Juggler is (C) Copyright 1998-2008 by Iowa State University
4 #
5 # Original Authors:
6 #   Allen Bierbaum, Christopher Just,
7 #   Patrick Hartling, Kevin Meinert,
8 #   Carolina Cruz-Neira, Albert Baker
9 #
10 # This library is free software; you can redistribute it and/or
11 # modify it under the terms of the GNU Library General Public
12 # License as published by the Free Software Foundation; either
13 # version 2 of the License, or (at your option) any later version.
14 #
15 # This library is distributed in the hope that it will be useful,
16 # but WITHOUT ANY WARRANTY; without even the implied warranty of
17 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18 # Library General Public License for more details.
19 #
20 # You should have received a copy of the GNU Library General Public
21 # License along with this library; if not, write to the
22 # Free Software Foundation, Inc., 59 Temple Place - Suite 330,
23 # Boston, MA 02111-1307, USA.
24 #
25 # *************** <auto-copyright.pl END do not edit this line> ***************
26
27 # -----------------------------------------------------------------------------
28 # Installation operations Perl 5 module.  This module defines the following
29 # subroutines for use in the Perl code that uses this.  The subroutines are
30 # (in alphabetical order):
31 #
32 #     - recurseDir(): Recurse through the given directory tree.
33 #     - setRecurseAction(): Set the function callback invoked by recurseDir().
34 #       The default is a function named recurseAction() in the calling module.
35 #     - newDir(): Create a new directory in a given directory tree.
36 #     - installFile(): Install a given file with specified permissions to a
37 #       destination directory.
38 #     - replaceTags(): Replace tags of the form "@...@" in the given file
39 #       with known replacment values.
40 # -----------------------------------------------------------------------------
41
42 package InstallOps;
43
44 require 5.003;
45
46 use Cwd;
47 use File::Basename;
48 use File::Copy;
49 use File::Path;
50
51 require Exporter;
52
53 @ISA = qw(Exporter);
54 @EXPORT = qw(setRecurseAction recurseDir newDir installFile replaceTags);
55
56 @dirstack = ();
57
58 my $caller = caller();
59 my $rec_func = \&{"${caller}::recurseAction"};
60
61 my $Win32 = 1 if $ENV{'OS'} =~ /Windows/;
62
63 sub recurseDir($$);
64
65 # -----------------------------------------------------------------------------
66 # Recurse through the given directory tree starting at $start_dir.  If a file
67 # is encountered, run &main::recurseAction() on that file.  The new directory
68 # tree that will be created is rooted at $base_inst_dir.  This routine
69 # requires that the calling package define a subroutine called
70 # "recurseAction()" that defines what actions to take when a normal file is
71 # encountered during the recursion process.
72 #
73 # Syntax:
74 #     recurseDir("$start_dir", "$base_inst_dir");
75 #
76 # Arguments:
77 #         $start_dir: The name of the directory from which the recursion
78 #                     begins.
79 #     $base_inst_dir: The base directory to which the existing directory
80 #                     tree will be installed.
81 # -----------------------------------------------------------------------------
82 sub recurseDir($$)
83 {
84    my $start_dir = shift;
85    my $base_inst_dir = shift;
86
87    # Save the current directory.
88    my $prevdir = cwd();
89
90    chdir("$start_dir") or die "ERROR: Cannot chdir to $start_dir: $!\n";
91
92    opendir(SRCDIR, ".");
93    my(@files) = readdir(SRCDIR);
94    closedir(SRCDIR);
95
96    my $curfile;
97
98    foreach $curfile ( @files )
99    {
100       next if $curfile =~ /^\.\.?$/;            # Skip . and ..
101
102       # $curfile is a directory.
103       if ( -d "$curfile" )
104       {
105          next if "$curfile" eq "CVS";           # Skip CVS directories
106          next if "$curfile" eq ".svn";          # Skip .svn directories
107
108          newDir("$base_inst_dir", "$curfile");
109          push(@dirstack, "$curfile");
110          recurseDir("$curfile", "$base_inst_dir");
111          pop(@dirstack);
112       }
113       # $curfile is something other than a directory (most likely a normal
114       # file).
115       else
116       {
117          # Pass &$rec_func only the current file name.
118          if ( $pass_rec_func_cur_file )
119          {
120             &$rec_func("$curfile");
121          }
122          # Pass &$rec_func the current file name and the current directory
123          # stack.
124          elsif ( $pass_rec_func_cur_file_dir )
125          {
126             &$rec_func("$curfile", join("/", @dirstack));
127          }
128          # Pass &$rec_func nothing.
129          else
130          {
131             &$rec_func();
132          }
133       }
134    }
135
136    # Go back to the previous directory so as not to intrude upon the actions
137    # of the caller.
138    chdir("$prevdir");
139 }
140
141 # -----------------------------------------------------------------------------
142 # Change the callback function used by recurseDir() to the specificed
143 # function reference.
144 #
145 # Syntax:
146 #     setRecruseAction($func_ref);
147 #
148 # Arguments:
149 #     $func_ref - A reference to a function that will be used as the callback
150 #                 invoked by recurseDir().  This is typically passed using the
151 #                 syntax \&funcName.
152 # -----------------------------------------------------------------------------
153 sub setRecurseActio($)
154 {
155    $rec_func = shift;
156 }
157
158 # -----------------------------------------------------------------------------
159 # Add a new directory ($newdir) to the directory tree rooted at $base_dir.
160 #
161 # Syntax:
162 #     newDir("$base_dir", "$newdir");
163 #
164 # Arguments:
165 #     $base_dir: The base of the directory tree to which the new directory
166 #                will be added.
167 #       $newdir: The new directory to add.
168 # -----------------------------------------------------------------------------
169 sub newDir($$)
170 {
171    my $base_dir = shift;
172    my $newdir = shift;
173
174    # Save the current directory.
175    my $prevdir = cwd();
176
177    # As long as $newdir does not exist, use mkpath() to create it.
178    if ( ! -d "$newdir" )
179    {
180       chdir("$base_dir")
181          or die "newDir(): WARNING: Could not chdir to $base_dir: $!\n";
182
183       umask(002);
184       mkpath("$newdir", 0, 0755)
185          or warn "newDir(): WARNING: Could not make $newdir: $!\n";
186    }
187
188    # Go back to the previous directory so as not to intrude upon the actions
189    # of the caller.
190    chdir("$prevdir");
191 }
192
193 # -----------------------------------------------------------------------------
194 # Install the given file with the specified permissions to the destination
195 # directory.
196 #
197 # Syntax:
198 #     $filename: The file to install.
199 #          $uid: The ID of the user who will own the file.
200 #          $gid: The ID of the group that will own the file.
201 #         $mode: The mode bits for the file.
202 #     $dest_dir: The destination directory for the file.
203 #    $make_link: Use a symlink instead of a file copy.  This argument is
204 #                optional, and it defaults to 0 (false) if not specified.
205 # -----------------------------------------------------------------------------
206 sub installFile($$$$$;$)
207 {
208    my $filename  = shift;
209    my $uid       = shift;
210    my $gid       = shift;
211    my $mode      = shift;
212    my $dest_dir  = shift;
213    my $make_link = shift || 0;
214
215    my $src_file = "$filename";
216
217    my $root = $dirstack[0];
218    $dirstack[0] = ".";
219    my $inst_path = join('/', @dirstack);
220    my $inst_dir = "$dest_dir/$inst_path";
221    $dirstack[0] = "$root";
222
223    print "$inst_path/$src_file ==> $inst_dir/$filename\n";
224
225    umask(002);
226
227    if ( ! -d "$inst_dir" )
228    {
229       warn "WARNING: Creating $inst_dir (incomplete installation hierarchy)!\n";
230       mkpath("$inst_dir", 0, 0755) or warn "mkpath: $!\n";
231    }
232
233    # If we are not on Win32 and a symlink was requested, use symlink() instead
234    # of copy().
235    if ( ! $Win32 && $make_link )
236    {
237       my $dest = "$inst_dir/$src_file";
238
239       if ( $src_file !~ /^\// )
240       {
241          my $cur_dir = getcwd();
242          $src_file   = "$cur_dir/$src_file";
243       }
244
245       unlink("$dest") if -e "$dest";
246       symlink("$src_file", "$dest")
247          or warn "WARNING: Failed to make symlink from $src_file to $dest: $!\n";
248    }
249    else
250    {
251       my @stats = (stat("$src_file"))[8,9];
252       copy("$src_file", "$inst_dir") or warn "copy: $!\n";
253       utime(@stats, "$inst_dir/$src_file");
254    }
255
256    # Do not try to change file ownership or permissions when we are using
257    # symlinks instead of file copies.
258    if ( ! $make_link )
259    {
260       if ( ! $Win32 )
261       {
262          chown($uid, $gid, "$inst_dir/$filename") or die "chown: $!\n";
263       }
264
265       chmod(oct($mode), "$inst_dir/$filename") or die "chmod: $!\n";
266    }
267 }
268
269 # -----------------------------------------------------------------------------
270 # Replace tags of the form "@...@" found in $infile with known values.  The
271 # values for the tags are given in the %VARS hash which is indexed by the tag
272 # name (without the surrounding @'s).
273 #
274 # Syntax:
275 #     $count = replaceTags("$infile", %VARS);
276 #
277 # Aguments:
278 #      $infile: The input file to be read.
279 #        %VARS: The hash of tags with replacement values.
280 #
281 # Returns:
282 #     The count of tags replaced in the input file (>= 0) on success.
283 #     -1 on error.
284 # -----------------------------------------------------------------------------
285 sub replaceTags($%)
286 {
287    my $infile = shift;
288    my(%VARS) = @_;
289
290    my $count = 0;
291
292    my $progname = (fileparse("$0"))[0];
293
294    # Open the input file, read its contents into @input_file and close it.
295    # Once it is in the array, we no longer need to worry about it.
296    if ( ! open(INPUT, "$infile") )
297    {
298       warn "WARNING: Cannot read from $infile: $!\n";
299       return -1;
300    }
301
302    my(@input_file) = <INPUT>;
303    close(INPUT) or warn "WARNING: Cannot close $infile: $!\n";
304
305    # Loop over all the lines in @input_array and replace occurrences of the
306    # tags (the keys of %VARS) with the corresponding values.
307    my $line;
308    foreach $line ( @input_file )
309    {
310       my $tag;
311       foreach $tag ( keys(%VARS) )
312       {
313          $count++ if $line =~ /\@$tag\@/;
314          $line =~ s/\@$tag\@/$VARS{"$tag"}/g;
315       }
316    }
317
318    # Create the output file by overwriting the input file.  The purpose is
319    # to replace the input file anyway, and overwriting it is the easiest way
320    # to accomplish this.
321    if ( ! open(OUTPUT, "> $infile") )
322    {
323       warn "WARNING: Cannot create $infile: $!\n";
324       return -1;
325    }
326
327    # Now generate the new output file using the contents of @input_file with
328    # all @..@ (that can be substituted) replaced.
329    foreach ( @input_file )
330    {
331       print OUTPUT;
332    }
333
334    close(OUTPUT) or warn "WARNING: Cannot save $infile: $!\n";
335
336    return $count;
337 }
338
339 1;
Note: See TracBrowser for help on using the browser.