File Coverage

blib/lib/Win32/Script.pm
Criterion Covered Total %
statement 344 944 36.4
branch 190 910 20.8
condition 56 406 13.7
subroutine 39 79 49.3
pod 49 51 96.0
total 678 2390 28.3


line stmt bran cond sub pod time code
1             # Win32::Script - System administrator`s library
2             # - for login and application startup scripts, etc
3             #
4             # makarow and demed
5             # ..., 18/02/99 13:04
6             #
7             package Win32::Script;
8             require 5.000;
9             require Exporter;
10 1     1   662 use Carp;
  1         2  
  1         105  
11 1     1   5 use vars qw($VERSION @ISA @EXPORT @EXPORT_OK %EXPORT_TAGS);
  1         2  
  1         172  
12             $VERSION = '0.58';
13             @ISA = qw(Exporter);
14             @EXPORT = qw(CPTranslate Die Echo FileACL FileCompare FileCopy FileCRC FileCwd FileDelete FileDigest FileEdit FileFind FileGlob FileHandle FileIni FileLnk FileMkDir FileNameMax FileNameMin FileRead FileSize FileSpace FileTrack FileWrite FTPCmd GUIMsg NetUse OLECreate OLEGet OLEIn OrArgs Pause Platform Print Registry Run RunInf RunKbd SMTPSend StrTime UserEnvInit UserPath WMIService WScript);
15             @EXPORT_OK = qw(FileLog TrAnsi2Oem TrOem2Ansi Try(@) TryHdr);
16             %EXPORT_TAGS = ('ALL'=>[@EXPORT,@EXPORT_OK],'OVER'=>[]);
17            
18 1     1   5 use vars qw($Interact $GUI $Echo $ErrorDie $Error $Print $Language %WScript);
  1         11  
  1         30345  
19             $Interact =1; # interaction with user; no: 0
20             $GUI =1; # use GUI interaction instead of terminal
21             $Echo =1; # set echo on
22             $ErrorDie =0; # die on errors: 1
23             $Error =''; # error result
24             $FileLog =''; # log file name (LOG handle) for Echo, Print, errors...
25             $Print =''; # external print routine hardlink
26             $Language =''; # language of user interaction, may be '' or 'ru'
27             %WScript =(); # Windows Script Host objects
28            
29             # FileHandle(\*STDOUT,sub{$| =1});
30             # FileHandle(\*STDERR,sub{$| =1});
31            
32             1;
33            
34             sub Try (@);
35            
36             sub import {
37 1 50   1   18 if (grep /^:OVER$/,@_) {
38 0 0       0 my $lst =(grep /^:ALL$/, @_) ? $EXPORT_TAGS{ALL} : \@EXPORT;
39 0         0 foreach my $elem (@$lst) {
40 0         0 my $sym =caller(1) .'::' .$elem; undef(&$sym);
  0         0  
41             }
42             }
43 1         3501 $_[0]->export_to_level(1, @_);
44             }
45            
46            
47             ###
48             sub CPTranslate {
49 0     0 1 0 my ($f,$t,@s) =@_;
50 0         0 foreach my $v ($f, $t) {
51 0 0       0 if ($v =~/oem|866/i) {$v ='񦧨'}
  0 0       0  
  0 0       0  
    0          
52 0         0 elsif ($v =~/ansi|1251/i) {$v ='Ũ'}
53 0         0 elsif ($v =~/koi/i) {$v ='ţ'}
54             elsif ($v =~/8859-5/i) {$v =''}
55             }
56 0         0 map {eval("~tr/$f/$t/")} @s;
  0         0  
57 0 0       0 @s >1 ? @s : $s[0];
58             }
59 0     0 1 0 sub TrOem2Ansi {CPTranslate('oem','ansi',@_)}
60 0     0 1 0 sub TrAnsi2Oem {CPTranslate('ansi','oem',@_)}
61            
62             ###
63             sub Die {
64 0 0   0 1 0 my @txt = @_ ? @_ : $@;
65 0 0 0     0 GUIMsg(($Language =~/ru/i ?'' :'Error')
    0 0        
    0          
66             , eval('${^ENCODING}') ? @txt : CPTranslate('oem','ansi',@txt))
67             if $Interact && $GUI && !$^S;
68 0 0       0 $! =1 if !$!;
69 0         0 croak(join(' ',@txt))
70             }
71            
72             ###
73 18 50   18 1 211 sub Echo { !$Echo || Print(@_)}
74            
75             ###
76             sub FileACL {
77 0     0 1 0 Try eval { local $ErrorDie =2;
  0         0  
78 0 0       0 my $opt =($_[0] =~/^\-/i ? shift : '');
79 0         0 my $file=shift;
80 0 0       0 my $sub =(ref($_[0]) eq 'CODE' ? shift : undef);
81 0         0 my %acl =@_;
82 0 0 0     0 if (!$sub && !grep {$_ !~/^(full|change|read)$/i} values(%acl)) {
  0         0  
83 0         0 my @c;
84 0 0       0 push @c, '/E' if $opt =~/\+/; push @c, '/T' if $opt =~/r/i;
  0 0       0  
85 0 0       0 push @c, ('/G', map {(index($_,' ') >=0 ?"\"$_\"" :$_) .':' .uc(substr($acl{$_},0,1))} sort(keys(%acl)));
  0         0  
86 0 0 0 0   0 push @c, sub{print("Y\n")} if $opt !~/\+/ && %acl;
  0         0  
87 0         0 return !grep {!Run('cacls.exe',"\"$_\"",'/C',@c)} FileGlob($file);
  0         0  
88             }
89 0         0 Echo('FileACL',$opt,$file,CPTranslate('ansi','oem',@_));
90 0 0   0   0 $sub =sub{1} if !$sub;
  0         0  
91 0         0 my (%acd, %acf);
92 0         0 eval('use Win32::FileSecurity');
93 0         0 foreach my $k (keys(%acl)) {
94 0 0       0 if (ref($acl{$k})) {$acd{$k} =Win32::FileSecurity::MakeMask(@$acl{$k}->[0]); $acf{$k} =Win32::FileSecurity::MakeMask(@$acl{$k}->[1])}
  0 0       0  
  0 0       0  
  0 0       0  
    0          
    0          
    0          
    0          
95 0         0 elsif ($acl{$k} =~/full/i) {$acd{$k} =Win32::FileSecurity::MakeMask(qw(FULL GENERIC_ALL)); $acf{$k} =Win32::FileSecurity::MakeMask(qw(FULL))}
  0         0  
96 0         0 elsif ($acl{$k} =~/change/i) {$acd{$k} =Win32::FileSecurity::MakeMask(qw(CHANGE GENERIC_WRITE GENERIC_READ GENERIC_EXECUTE)); $acf{$k} =Win32::FileSecurity::MakeMask(qw(CHANGE))}
  0         0  
97 0         0 elsif ($acl{$k} =~/add&read/i) {$acd{$k} =Win32::FileSecurity::MakeMask(qw(ADD GENERIC_READ GENERIC_EXECUTE)); $acf{$k} =Win32::FileSecurity::MakeMask(qw(READ))}
  0         0  
98 0         0 elsif ($acl{$k} =~/add&list/i) {$acd{$k} =Win32::FileSecurity::MakeMask(qw(ADD READ STANDARD_RIGHTS_READ STANDARD_RIGHTS_WRITE STANDARD_RIGHTS_EXECUTE READ_CONTROL SYNCHRONIZE))}
99             # in doubt^
100 0         0 elsif ($acl{$k} =~/add/i) {$acd{$k} =Win32::FileSecurity::MakeMask(qw(STANDARD_RIGHTS_READ STANDARD_RIGHTS_WRITE STANDARD_RIGHTS_EXECUTE READ_CONTROL SYNCHRONIZE))}
101             # in very doubt^
102 0         0 elsif ($acl{$k} =~/read/i) {$acd{$k} =Win32::FileSecurity::MakeMask(qw(READ GENERIC_READ GENERIC_EXECUTE)); $acf{$k} =Win32::FileSecurity::MakeMask(qw(READ))}
  0         0  
103             elsif ($acl{$k} =~/list/i) {$acd{$k} =Win32::FileSecurity::MakeMask(qw(READ_CONTROL SYNCHRONIZE STANDARD_RIGHTS_READ STANDARD_RIGHTS_WRITE STANDARD_RIGHTS_EXECUTE READ))}
104             # in doubt^
105             };
106             FileFind($file
107 0 0   0   0 ,sub{ print STDOUT "$_\n" if $Echo;
108 0 0       0 if (!&$sub(@_)) {}
    0          
109             elsif ($_[0]->[2] & 0040000) {
110 0 0       0 if (!scalar(%acd)) {eval{my %h; Win32::FileSecurity::Get($_,\%h); foreach my $k (sort(keys(%h))){my @s; Win32::FileSecurity::EnumerateRights($h{$k},\@s); Echo($k,'=>',@s)}}}
  0 0       0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
111 0         0 elsif ($opt =~/\+/i) {eval{my %h; Win32::FileSecurity::Get($_,\%h); foreach my $k (keys(%acd)){$h{$k}=$acd{$k}}; Win32::FileSecurity::Set($_,\%h)}}
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
112 0         0 else {eval{Win32::FileSecurity::Set($_,\%acd)}}
113 0 0       0 $_[0]->[2] =0 if $opt !~/r/i;
114             }
115             else {
116 0 0       0 if (!scalar(%acf)) {eval{my %h; Win32::FileSecurity::Get($_,\%h); foreach my $k (sort(keys(%h))){my @s; Win32::FileSecurity::EnumerateRights($h{$k},\@s); Echo($k,'=>',@s)}}}
  0 0       0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
117 0         0 elsif ($opt =~/\+/i) {eval{my %h; Win32::FileSecurity::Get($_,\%h); foreach my $k (keys(%acf)){$h{$k}=$acf{$k}}; Win32::FileSecurity::Set($_,\%h)}}
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
118 0         0 else {eval{Win32::FileSecurity::Set($_,\%acf)}}
119             }})
120 0         0 },0}
121            
122             ###
123             sub FileCompare {
124 1 50   1 1 89 my $opt =($_[0] =~/^\-/i ? shift : '');
125 1     1   958 my $ret =eval("use File::Compare; compare(\@_)");
  1         1213  
  1         59  
  1         54  
126 1 0 33     222 if ($@ || $ret <0) {TryEnd(($Language =~/ru/i ?'㤠筮 ࠢ' :'Failure')." compare(" .join(', ',@_) ."): $!"); 0}
  0 50       0  
  0         0  
  1         21  
127             else {$ret}
128             }
129            
130             ###
131             sub FileCopy {
132 1     1 1 86 Try eval { local $ErrorDie =2;
  1         3  
133 1 50       7 my $opt =$_[0] =~/^-/i ?shift :''; $opt =~s/-//g;
  1         6  
134             # 'd'irectory or 'f'ile hint; 'r'ecurse subdirectories, 'i'gnore errors
135 1 50       2 my ($src,$dst) =@_; if ($^O eq 'MSWin32') {$src =~tr/\//\\/; $dst =~tr/\//\\/}
  1         9  
  0         0  
  0         0  
136 1 50 33     72 if ($^O ne 'dos' && $] >=5.006 && $src !~/[?*]/ && $dst !~/[?*]/ && -s $src <2*1024*1024 && !-d $src
    0 33        
      33        
      33        
      33        
      33        
      33        
137             && (-e $dst ||($opt !~/d/ && $dst =~/(.+)[\\\/][^\\\/]+$/ ? -d $1 : 0))) {
138 1 0       599 $dst .=($dst =~/[\\\/]$/ ? '' : $^O eq 'MSWin32' ? '\\' : '/') .($src =~/[\\\/]([^\\\/]+)$/ ? $1 : $src) if -d $dst;
    0          
    0          
    50          
139 1         7 Echo("CopyFile('$src', '$dst')");
140 1 50 33 1   1098 ((-f $dst ?unlink($dst) :1) && ($^O eq 'MSWin32' ?Win32::CopyFile($src, $dst, 1) :eval("use File::Copy; File::Copy::copy('$src','$dst')")))
  1 50       2731  
  1 50       65  
  1         334  
141             ||croak("CopyFile('$src','$dst')->$!")
142             }
143             elsif ($^O =~/MSWin32|dos/) {
144 0 0 0     0 $opt .='Z' .((eval{(Win32::GetOSVersion())[1]} ||eval('use Win32::TieRegistry; $$Registry{\'LMachine\\Software\\Microsoft\\Windows NT\\CurrentVersion\\\\CurrentVersion\'}') ||0) >=5 ?'Y' :'')
    0 0        
145             if ($ENV{OS}||'') =~/Windows_NT/i;
146 0 0       0 my $rsp =($opt =~/d/i ? 'D' : $opt =~/f/i ? 'F' : '');
    0          
147 0         0 $opt =~s/(r)/SE/i; $opt =~s/(i)/C/i; $opt =~s/[fd]//ig; $opt =~s/(.{1})/\/$1/gi;
  0         0  
  0         0  
  0         0  
148 0         0 my @cmd =('xcopy',"/H/R/K/Q$opt","\"$src\"","\"$dst\"");
149 0 0 0 0   0 push @cmd, sub{print($rsp)} if $rsp && ($ENV{OS} && $ENV{OS}=~/windows_nt/i ? !-e $dst : !-d $dst);
  0 0 0     0  
150 0         0 Run(@cmd)
151             }
152             else {
153 0         0 $opt =~ tr/fd//; $opt ="-${opt}p"; $opt =~ tr/ri/Rf/; Run('cp', $opt, @_)
  0         0  
  0         0  
  0         0  
154             }
155             },0}
156            
157             ###
158             sub FileCRC {
159 1     1 1 83 Try eval { local $ErrorDie =2;
  1         3  
160 1 50       5 my $opt =($_[0] =~/^\-/i ? shift : '');
161 1         2 my ($file) =@_;
162 1         3 my $bufsze =64*1024;
163 1         2 my $buff;
164 1         1 my $crc =0;
165 1         3 local *IN;
166 1     1   17546 eval("use Compress::Zlib");
  1         97306  
  1         307  
  1         59  
167 1 0       57 open(IN, "<$file") || croak(($Language =~/ru/i ?'⨥' :'Opening') ." '<$file': $!");
    50          
168 1         4 binmode(IN);
169 1         13 while (!eof(IN)) {
170 1 0       18 defined(read(IN, $buff, $bufsze)) || croak(($Language =~/ru/i ?'⥭' :'Reading')." '<$file': $!");
    50          
171 1 50       23 $crc = $opt =~/\-a? ?adler/i ? adler32($buff,$crc) : crc32($buff,$crc);
172             }
173 1 0       17 close(IN) || croak(($Language =~/ru/i ?'⨥' :'Closing')." '<$file': $!");
    50          
174 1         10 $crc;
175             },0}
176            
177             ###
178             sub FileCwd {
179 1     1 1 8 eval('use Cwd; getcwd()')
  1     1   2  
  1         62  
  1         145  
180             }
181            
182             ###
183             sub FileDelete {
184 4     4 1 338 Try eval { local $ErrorDie =2;
  4         7  
185 4         16 Echo('FileDelete',@_);
186 4 100 66     38 my $opt =$_[0] =~/^\-/ || $_[0] eq '' ? shift : '';
187 4         7 my $ret =1;
188 4         12 foreach my $par (@_) {
189 4         20 foreach my $elem (FileGlob($par)) {
190 4 50 33     74 if (-d $elem) { # '-r' - recurse subdirectories
    50          
191 0 0 0     0 if ($opt =~/r/i && !FileDelete($opt,"$elem/*")) {
    0          
192 0         0 $ret =0
193             }
194             elsif (!rmdir($elem)) {
195 0         0 $ret =0;
196 0 0       0 $opt =~/i/i || croak(($Language =~/ru/i ?'' :'Deleting')." FileDelete('$elem'): $!");
    0          
197             }
198             }
199             elsif (-f $elem && !unlink($elem)) {
200 0         0 $ret =0;
201 0 0       0 $opt =~/i/i || croak(($Language =~/ru/i ?'' :'Deleting')." FileDelete('$elem'): $!");
    0          
202             }
203             }
204             }
205             $ret
206 4         17 },0}
207            
208             ###
209             sub FileDigest {
210 0     0 1 0 Try eval { local $ErrorDie =2;
  0         0  
211 0 0       0 my $m = substr($_[0] =~/^-/i ? shift : '-MD5', 1);
212 0     0   0 FileHandle($_[0],sub{eval("use Digest::${m};Digest::${m}->new->addfile(*HANDLE)->hexdigest")})
213 0         0 },0}
214            
215             ###
216             sub FileEdit {
217 1     1 1 79 Try eval { local $ErrorDie =2;
  1         3  
218 1         5 Echo("FileEdit",@_);
219 1 50       4 my $opt = $_[0] =~/^-/i ? shift : '-i';
220 1         3 my $file = shift;
221 1 50       7 my $fileto = @_ >1 ? shift : ''; if($fileto =~/^-/i) {$opt =$opt .$fileto; $fileto =''};
  1 50       4  
  0         0  
  0         0  
222 1         2 my $sub = shift;
223 1 50       6 my $mtd = $opt =~/^\-i/i ? 1 : 0;
224 1         5 my ($sct,@v) =('','','','');
225 1         2 local $_;
226            
227 1 50       4 if ($opt =~/^\-i$/i) { # '-i' - default, in memory inplace edit
    0          
228 1         2 my @dta;
229 1         2 $mtd =0;
230 1         6 foreach my $row (FileRead($file)) {
231 6         9 $_ =$row;
232 6 100       22 $sct =$1 if /^\s*[\[]([^\]]*)/;
233 6         8 &{$sub}($sct, @v); # &{$sub}($sct, @v);
  6         18  
234 6 100 66     53 $mtd =1 if !defined($_) || $_ ne $row;
235 6 50       18 push(@dta, $_) if defined($_);
236             }
237 1   33     11 return(!$mtd || FileWrite($file, @dta));
238             }
239             elsif ($opt =~/^-m$/i) { # '-m' - multiline edit in memory
240 0         0 $fileto = $_ =FileRead($file);
241 0         0 &{$sub}($sct, @v); # &{$sub}($sct, @v);
  0         0  
242 0   0     0 return(($fileto eq $_) || FileWrite($file, $_));
243             }
244             # '-i ext' or 'from, to'
245 0 0       0 $fileto ="$file.$1" if $opt =~/^\-i\s*(.*)/i;
246 0 0 0     0 if (!-f $file && -f $fileto) {
247 0         0 Echo("copy", $fileto, $file);
248 0         0 eval ("use File::Copy");
249 0 0       0 File::Copy::copy ($fileto, $file) || croak(($Language =~/ru/i ?'஢' :'Copying')." '$fileto'->'$file': $!");
    0          
250             }
251 0         0 local (*IN, *OUT);
252 0 0       0 open(IN, "<$file") || croak(($Language =~/ru/i ?'⨥' :'Opening')." '<$file': $!");
    0          
253 0 0       0 open(OUT, ">$fileto") || croak(($Language =~/ru/i ?'⨥' :'Opening')." '>$fileto': $!");
    0          
254 0         0 while (!eof(IN)) {
255 0 0       0 defined($_ =) || croak("⥭ '<$file': $!");
256 0         0 chomp;
257 0 0       0 $sct =$1 if /^\s*[\[]([^\]]*)/;
258 0         0 &{$sub}(@v); # &{$sub}($sct, @v);
  0         0  
259 0 0 0     0 !defined($_) || print(OUT $_,"\n") || croak(($Language =~/ru/i ?'' :'Writing')." '>$fileto': $!");
    0          
260             }
261 0 0       0 close(IN) || croak(($Language =~/ru/i ?'⨥' :'Closing')." '<$file': $!");
    0          
262 0 0       0 close(OUT) || croak(($Language =~/ru/i ?'⨥' :'Closing')." '>$fileto': $!");
    0          
263 0 0 0     0 !$mtd || rename($fileto, $file) || croak(($Language =~/ru/i ?'२' :'Renaming')." '$file'->'$fileto': $!");
    0          
264 0         0 1;
265             },0}
266            
267             ###
268             sub FileFind {
269 2     2 1 92 Try eval { local $ErrorDie =2;
  2         4  
270 2 100       11 my $opt =($_[0] =~/^\-/i ? shift : '');
271 2         5 my ($sub, $i, $ret) =(0,0,0);
272 2 50       9 local ($_, $result) if $opt !~/-\$/i;
273 2 50       8 $opt =$opt ."-\$" if $opt !~/-\$/i;
274 2         6 foreach my $dir (@_) {
275 3         5 $i++;
276 3 100 66     47 if ((!$sub || ref($dir)) && ref($_[$#_]) && $i <=$#_) {
    50 33        
      66        
277 2 50       9 foreach my $elem (@_[$i..$#_]){if(ref($elem)){$sub =$elem; last}};
  2         8  
  2         3  
  2         5  
278 2 50       6 next if ref($dir)
279             }
280             elsif (ref($dir)) {
281 1         2 $sub =$dir; next
282 1         3 }
283 2         5 my $fs;
284 2 100       15 foreach my $elem ($opt =~/[^!]*i/i ?eval{FileGlob($dir)} :FileGlob($dir)) {
  1         4  
285 2         6 $_ =$elem;
286 2         14 my @stat =stat($elem);
287 2 50       10 my @nme =(/^(.*)[\/\\]([^\/\\]+)$/ ? ($1,$2) : ('',''));
288 2 50 66     59 if (@stat ==0 && ($opt =~/[^!]*i/i || ($^O eq 'MSWin32' && $elem =~/[\?]/i))) {next} # bug in stat!
  1 100 33     5  
  1 50 0     262  
    0 0        
    0          
    0          
289 0         0 elsif (@stat ==0) {croak(($Language =~/ru/i ?'㤠祭' :'Failure')." stat('$elem'): $!"); undef($_); return(0)}
  0         0  
  0         0  
290 0         0 elsif ($stat[2] & 0120000 && $opt =~/!.*s/i) {next} # symlink
291 0         0 elsif (!defined($fs)) {$fs =$stat[2]}
292             elsif ($fs !=$stat[2] && $opt =~/!.*m/i) {next} # mountpoint?
293 0 0 0     0 if ($stat[2] & 0040000 && $opt =~/!.*l/i) { # finddepth
294 0 0       0 $ret +=FileFind($opt, "$elem/*", $sub); defined($_) || return(0);
  0         0  
295 0         0 $_ =$elem;
296             }
297 0 0 0     0 if ($stat[2] & 0040000 && $opt =~/!.*d/i) {} # exclude dirs
  0 0       0  
298             elsif (&$sub(\@stat,@nme,$result)) {$ret +=1}; # $_[3] - optional result
299 0 0       0 defined($_) || return(0); # error stop: undef($_)
300 0 0 0     0 if ($stat[2] & 0040000 && $opt !~/!.*[rl]/i) { # no recurse, $_[0]->[2] =0
301 0 0       0 $ret +=FileFind($opt, "$elem/*", $sub); defined($_) || return(0);
  0         0  
302             }
303             }
304             }
305 1 50       6 defined($result) ? $result : $ret
306             },0}
307            
308             ###
309             sub FileGlob {
310 10 50   10 1 322 $^O eq 'MSWin32' ? FileDosGlob(@_) : glob(@_)
311             }
312            
313             ###
314             sub FileDosGlob {
315 0     0 0 0 my @ret;
316 0         0 Try eval { local $ErrorDie =2;
  0         0  
317 0 0       0 if (-e $_[0]) {
318 0         0 push @ret, $_[0];
319             }
320             else {
321 0 0       0 my $msk =($_[0] =~/([^\/\\]+)$/i ? $1 : '');
322 0         0 my $pth =substr($_[0],0,-length($msk));
323 0         0 $msk =~s/\*\.\*/*/g;
324 0         0 $msk =~s:(\(\)[].+^\-\${}[|]):\\$1:g;
325 0         0 $msk =~s/\*/.*/g;
326 0         0 $msk =~s/\?/.?/g;
327 0 0       0 local (*DIR, $_); opendir(DIR, $pth eq '' ? './' : $pth) || croak(($Language =~/ru/i ?'⨥ ⠫' :'Opening directory')." '$pth': $!");
  0 0       0  
    0          
328             # print "FileGlob: '$pth' : '$msk'\n";
329 0         0 while(defined($_ =readdir(DIR))) {
330 0 0 0     0 next if $_ eq '.' || $_ eq '..' || $_ !~/^$msk$/i;
      0        
331 0         0 push @ret, "${pth}$_";
332             }
333 0 0       0 closedir(DIR) || croak(($Language =~/ru/i ?'⨥ ⠫' :'Closing directory')." '$pth': $!");
    0          
334             }
335             }, undef;
336 0         0 @ret;
337             }
338            
339             ###
340             sub FileHandle {
341 1     1 1 83 Try eval { local $ErrorDie =2;
  1         3  
342 1         3 my ($file,$sub)=@_;
343 1         3 my $hdl =select();
344 1         2 my $ret;
345 1 50 33     10 if (ref($file) || ref(\$file) eq 'GLOB') {select(*$file); $ret =&$sub($hdl); select($hdl)}
  0         0  
  0         0  
  0         0  
346             else {
347 1 50       5 my $c =(caller(1) ? caller(1) .'::' : '');
348 1 0       2 local *{"${c}HANDLE"}; open("${c}HANDLE", $file) || croak(($Language =~/ru/i ?'⨥' :'Opening')." '$file': $!");
  1 50       5  
  1         37  
349 1         5 select ("${c}HANDLE"); $ret =&$sub($hdl); select($hdl);
  1         4  
  1         38  
350 1 0       16 close ("${c}HANDLE") || croak(($Language =~/ru/i ?'⨥' :'Closing')." '$file': $!");
    50          
351             }
352 1         5 $ret;
353             },''}
354            
355             ###
356             sub FileIni {
357 1     1 1 82 Try eval { local $ErrorDie =2;
  1         2  
358 1 50       7 my $opt =$_[0] =~/^-/i ? shift : '';
359 1         2 my $file =shift;
360 1         4 Echo("FileIni",$opt,$file);
361 1         2 my @ini =FileRead($file);
362 1         3 my ($sct, $nme, $val, $op);
363 1         2 my ($isct, $inme, $iins, $val1) =(-1);
364 1         3 my $mod =0;
365            
366             # Return hash with ini-file data:
367 1 50       4 if (scalar(@_)<=0) {
368 0         0 my %dta;
369 0         0 foreach my $row (@ini) {
370 0         0 $row =~/^\s*(.*?)\s*$/; $row =$1;
  0         0  
371 0 0       0 if ($row =~/^[\[]/i) {$sct =$row; $dta{$sct}={}}
  0 0       0  
  0         0  
372 0         0 elsif ($row =~/^[;]/i) {}
373 0         0 else {$row =~/^([^\=]*?)\s*=\s*(.*)/i; $dta{$sct}->{$1}=$2;}
374             }
375 0         0 return(\%dta);
376             }
377            
378             # Edit ini-file with @_ entries:
379             # '[section]' , ';comment' , [data,value] or
380             # ['[section]',op], [';comment',op], [data,value,op]
381             # op: '+'set (default), '-'del, ';'comment, 'i'nitial vaue, 'o'ptional value
382 1         3 foreach my $row (@_) {
383 4 100       26 if ((ref($row) ? $$row[0] : $row) =~/^\s*[\[]/i) {
    50          
    100          
    50          
384 1 50       3 $sct =ref($row) ? $$row[0] : $row; $nme =undef; $val =undef;
  1         27  
  1         3  
385 1 50 0     3 $op =ref($row) ? $$row[1] || '+' : '+';
386 1         2 $isct=-1;
387 1         8 for(my $i =0; $i <=$#ini; $i++) {
388 1 50       4 next if !$ini[$i];
389 1 50       34 if ($ini[$i]=~/^\s*\Q$sct\E\s*$/i) {$isct =$i; last};
  1         2  
  1         2  
390             }
391             # print "$sct : $isct : ".($isct==-1 ? "" : $ini[$isct])."\n";
392 1 50 33     17 if ($op =~/[\+i]/i && $isct ==-1) {$mod =1; push(@ini, $sct); $isct =$#ini}
  0 50       0  
  0 50       0  
  0 50       0  
393             elsif ($isct ==-1) {}
394             elsif ($op =~/[\;]/i) {
395 0         0 $mod =1; $ini[$isct] =';' .$ini[$isct];
  0         0  
396 0   0     0 for(my $i =$isct+1; $i <=$#ini && $ini[$i] !~/^\s*[\[]/i; $i++) {
397 0         0 $ini[$i] =';' .$ini[$i]
398             }
399             }
400             elsif ($op =~/[\-]/i) {
401 0         0 $mod =1; undef($ini[$isct]);
  0         0  
402 0   0     0 for(my $i =$isct+1; $i <=$#ini && $ini[$i] !~/^\s*[\[]/i; $i++) {
403 0         0 undef($ini[$i])
404             }
405             }
406             }
407             elsif ((ref($row) ? $$row[0] : $row) =~/^\s*[\;]/i) {
408 0 0       0 $nme =ref($row) ? $$row[0] : $row; $val =undef;
  0         0  
409 0 0 0     0 $op =ref($row) ? $$row[1] || '+' : '+';
410 0         0 $inme=-1; $iins =$#ini +1;
  0         0  
411 0         0 for(my $i =$isct+1; $i <=$#ini; $i++) {
412 0 0       0 next if !$ini[$i];
413 0 0       0 if ($ini[$i] =~/^\s*[\[]/i) {$iins =$i; last}
  0         0  
  0         0  
414 0 0       0 if ($ini[$i]=~/^\s*\Q$nme\E\s*$/i) {$inme =$i; last}
  0         0  
  0         0  
415             }
416 0 0 0     0 if ($op =~/[\-]/i && $inme !=-1) {$mod =1; undef($ini[$inme])}
  0 0 0     0  
  0         0  
  0         0  
417 0         0 elsif ($op =~/[\+]/i && $inme ==-1) {$mod =1; splice(@ini, $iins, 0, $nme)}
418             }
419             else {
420 3         6 $nme =$$row[0]; $val =$$row[1];
  3         4  
421 3   66     11 $op =$$row[2] || (!defined($$row[1]) ? '-' : '+');
422 3         4 $inme=-1; $iins =$#ini +1; $val1='';
  3         4  
  3         4  
423 3         20 for(my $i =$isct+1; $i <=$#ini; $i++) {
424 8 50       17 next if !$ini[$i];
425 8 100       19 if ($ini[$i] =~/^\s*[\[]/i) {$iins =$i; last}
  2         3  
  2         3  
426 6 100       84 if ($ini[$i]=~/^\s*\Q$nme\E\s*=/i)
  1         2  
427 1 50       9 {$inme =$i; $val1 =$1 if $ini[$i]=~/=\s*(.*?)\s*$/i; last}
  1         3  
428             }
429             # print "$nme=>$val : [$inme..$iins] : $val1\n";
430 3 100 100     33 if ($op =~/[\+i]/i && $inme ==-1) {$mod =1; splice(@ini, $iins, 0, "$nme=$val")}
  1 100 33     2  
  1 50       5  
    50          
    50          
431 0         0 elsif ($inme ==-1) {}
432 0         0 elsif ($op =~/[;]/i) {$mod =1; $ini[$inme] =';'.$ini[$inme]}
  0         0  
433 0         0 elsif ($op =~/[\-]/i) {$mod =1; undef($ini[$inme])}
  1         2  
434 1         4 elsif ($op =~/[\+o]/ && $val ne $val1) {$mod =1; $ini[$inme] ="$nme=$val"}
435             }
436             }
437 1 50       7 !$mod || FileWrite($file,@ini);
438             },0}
439            
440            
441             ###
442             sub FileLnk {
443 0     0 1 0 Try eval { local $ErrorDie =2;
  0         0  
444 0         0 eval('use Win32::Shortcut');
445 0 0 0     0 my $opt =(@_ && $_[0] =~/^-/i ? shift : '');
446 0 0       0 my $f =@_ ? shift : undef;
447 0 0 0     0 $f =$f .'.lnk' if defined($f) && $f !~/\./i;
448 0 0 0     0 if (defined($f) && $opt =~/[mda]/i) {$f =UserPath($opt =~/a/i ?'all' :'', $opt =~/d/i ?'Desktop' :'Start Menu') .'/' .$f};
  0 0       0  
    0          
449 0 0       0 return Win32::Shortcut->new($f) if !@_;
450 0         0 Echo('FileLnk',$opt,$f,@_);
451 0 0       0 my $l =Win32::Shortcut->new($opt =~/c/i ? undef : $f);
452 0 0       0 if (ref($_[0])) {
453 0         0 foreach my $k (keys(%{$_[0]})) {
  0         0  
454 0 0       0 my $m =($k =~/path|targ/i ? 'Path'
    0          
    0          
    0          
    0          
    0          
    0          
    0          
455             :$k =~/arg/i ? 'Arguments'
456             :$k =~/work|dir/i ? 'WorkingDirectory'
457             :$k =~/desc|dsc/i ? 'Description'
458             :$k =~/show/i ? 'ShowCmd'
459             :$k =~/hot/i ? 'Hotkey'
460             :$k =~/i.*l/i ? 'IconLocation'
461             :$k =~/i.*n/i ? 'IconNumber'
462             :$k);
463 0         0 $l->{$m} =$_[0]->{$k};
464             }
465             }
466             else { # $l->Set(@_)
467 0 0       0 $l->{'Path'} =$_[0] if defined($_[0]);
468 0 0       0 $l->{'Arguments'} =$_[1] if defined($_[1]);
469 0 0       0 $l->{'WorkingDirectory'} =$_[2] if defined($_[2]);
470 0 0       0 $l->{'Description'} =$_[3] if defined($_[3]);
471 0 0       0 $l->{'ShowCmd'} =$_[4] if defined($_[4]);
472 0 0       0 $l->{'Hotkey'} =$_[5] if defined($_[5]);
473 0 0       0 $l->{'IconLocation'} =$_[6] if defined($_[6]);
474 0 0       0 $l->{'IconNumber'} =$_[7] if defined($_[7]);
475             }
476 0         0 $l->Save($f)
477             },''}
478            
479             ###
480             sub FileLog {
481 0     0 1 0 Try eval {
482 0 0       0 return $FileLog if !@_;
483 0 0 0     0 return (close(LOG),$FileLog ='') if @_ && !defined($_[0]) && $FileLog ne '';
      0        
484 0 0       0 open(LOG, ">>$_[0]") || croak(($Language =~/ru/i ?'⨥' :'Opening')." '>>$_[0]': $!");
    0          
485 0     0   0 $SIG{__WARN__} =sub{Print(@_)};
  0         0  
486 0 0 0 0   0 $SIG{__DIE__} =sub{!defined($^S) || $^S ? die(@_) : Print(@_)};
  0         0  
487 0         0 $FileLog =$_[0];
488             },''}
489            
490             ###
491             sub FileMkDir {
492 2     2 1 301 Try eval { local $ErrorDie =2;
  2         6  
493 2         6 my ($dir, $mask) =@_;
494 2         13 Echo('mkdir', @_);
495 2 50 50     1080 mkdir($dir, $mask || 0777) || croak(($Language =~/ru/i ?'' :'Creating').' '.join(', ',@_) .": $!");
    50          
496             },0}
497            
498             ###
499             sub FileNameMax {
500 1     1 1 76 my ($dir, $sub) =@_;
501 1         3 my ($max, $nme) =(undef,'');
502 1         2 local $_;
503 1         2 eval { local $ErrorDie =2;
  1         2  
504 1 50       9 foreach my $elem (FileGlob($dir =~/[\?\*]/ ? $dir : "$dir/*")) {
505 0 0 0     0 next if !$elem || -d $elem;
506 0 0       0 my $nmb =($sub ? &$sub($elem, ($_ =$elem =~/([^\\\/]+)$/i ? $1 :''), ($elem =~/([\d]+)[^\\\/]*$/ ? $1 : undef))
    0          
    0          
    0          
507             : ($elem =~/([\d]+)[^\\\/]*$/ ? $1 : undef));
508 0 0 0     0 if (defined($nmb) && (!$max || $max <$nmb)) {$max =$nmb; $nme =$elem};
  0   0     0  
  0         0  
509             }
510 1 50       6 }; if ($@) {$max =undef; $nme =''; TryEnd()}
  0         0  
  0         0  
  0         0  
511 1 50       15 wantarray ? ($nme, $max) : $max;
512             }
513            
514             ###
515             sub FileNameMin {
516 1     1 1 70 my ($dir, $sub) =@_;
517 1         3 my ($min, $nme) =(undef,'');
518 1         3 local $_;
519 1         2 eval { local $ErrorDie =2;
  1         2  
520 1 50       7 foreach my $elem (FileGlob($dir =~/[\?\*]/ ? $dir : "$dir/*")) {
521 1 50 33     21 next if !$elem || -d $elem || $elem !~/([\d]+)[^\\\/]*$/;
      33        
522 1 0       9 my $nmb =($sub ? &$sub($elem, ($_ =$elem =~/([^\\\/]+)$/i ? $1 :''), ($elem =~/([\d]+)[^\\\/]*$/ ? $1 : undef))
    0          
    50          
    50          
523             : ($elem =~/([\d]+)[^\\\/]*$/ ? $1 : undef));
524 1 50 33     8 if (defined($nmb) && (!$min || $min >$nmb)) {$min =$nmb; $nme =$elem;}
  1   33     1  
  1         4  
525             }
526 1 50       4 }; if ($@) {$min =undef; $nme =''; TryEnd()}
  0         0  
  0         0  
  0         0  
527 1 50       17 wantarray ? ($nme, $min) : $nme;
528             }
529            
530             ###
531             sub FileRead {
532 3 50   3 1 280 my $opt =($_[0] =~/^\-/i ? shift : ''); # 'a'rray, 's'calar, 'b'inary
533 3 100 66     21 $opt =$opt .'a' if $opt !~/[asb]/i && wantarray;
534 3         6 my ($file, $sub) =@_;
535 3         4 my ($row, @rez);
536 3         67 local *IN;
537 3         7 eval { local $ErrorDie =2;
  3         4  
538 3 0       107 open(IN, "<$file") || croak(($Language =~/ru/i ?'⨥' :'Opening')." '<$file': $!");
    50          
539 3 50       19 if ($sub) {
    100          
540 0         0 $row =1;
541 0         0 local $_;
542 0         0 while (!eof(IN)) {
543 0 0       0 defined($_ =) || croak(($Language =~/ru/i ?'⥭' :'Reading')." '<$file': $!");
    0          
544 0         0 chomp;
545 0 0 0     0 $opt=~/a/i ? &$sub() && push(@rez,$_)
546             : &$sub();
547             }
548             }
549             elsif ($opt=~/a/i) {
550 2         48 while (!eof(IN)) {
551 12 0       29 defined($row =) || croak(($Language =~/ru/i ?'⥭' :'Reading')." '<$file': $!");
    50          
552 12         14 chomp($row);
553 12         36 push (@rez, $row);
554             }
555             }
556             else {
557 1 50       4 binmode(IN) if $opt =~/b/i;
558 1 0       23 defined(read(IN, $row, -s $file)) || croak(($Language =~/ru/i ?'⥭' :'Reading')." '<$file': $!");
    50          
559             }
560 3 0       46 close(IN) || croak(($Language =~/ru/i ?'⨥' :'Closing')." '<$file': $!");
    50          
561 3 50       9 }; if ($@) {@rez =(); $row =''; TryEnd()}
  0         0  
  0         0  
  0         0  
562 3 100       37 $opt=~/a/i ? @rez : $row
563             }
564            
565             ###
566             sub FileSize {
567 1 50   1 1 78 my $opt =($_[0] =~/^\-/i ? shift : '-i');
568 1         2 my $file=shift;
569 1 50   0   9 my $sub =(ref($_[0]) ? shift : sub{1});
  0         0  
570 0 0   0   0 FileFind($opt,$file, sub{$_[3] +=$_[0]->[7] if &$sub(@_)})
571 1         9 }
572            
573             ###
574             sub FileSpace {
575 1     1 1 85 Try eval { local $ErrorDie =2;
  1         3  
576 1   50     7 my $disk =$_[0] || "c:\\";
577 1         2 my $sze;
578 1 50       5 if ($^O eq 'MSWin32') {
579 0 0       0 if (eval('use Win32::API; 1')) {
580 0         0 my ($f, $sc, $sb, $nf, $nt) =(undef,"\0"x8,"\0"x8,"\0"x8,"\0"x8);
581 0 0 0     0 return unpack('L',substr($nf,4)) *(1+0xFFFFFFFF) +unpack('L',substr($nf,0,4)) # unpack('Q',$nf)
582             if 1 && ($f =new Win32::API('kernel32', 'GetDiskFreeSpaceEx', [qw(P P P P)], 'N'))
583             && $f->Call("$disk\0",$sc,$sb,$nf);
584 0 0 0     0 return unpack('L',$sc) *unpack('L',$sb) *unpack('L',$nf)
585             if ($f =new Win32::API('kernel32', 'GetDiskFreeSpace', [qw(P P P P P)], 'N'))
586             && $f->Call("$disk\0",$sc,$sb,$nf,$nt);
587             }
588 0 0       0 $sze =`\%COMSPEC\% /c dir $disk`=~/([\d\.\xFF, ]+)[\D]*$/i ? $1 : ''
589             }
590             else {
591 1 50       14143 $sze =`df -k` =~/^$disk +([\d]+)/im ? $1 : ''
592             }
593 1         11 $sze =~ s/[\xFF, ]//g;
594 1 50       949 $sze eq '' && croak("FileSpace($disk) -> $?)");
595 0         0 $sze
596             },0}
597            
598             ###
599             sub FileTrack {
600 1     1 1 87 Try eval { local $ErrorDie =2;
  1         3  
601 1 50       235 my $opt =($_[0] =~/^\-/i ? shift : '-');
602 1         73 my ($src,$dst,$sub) =@_;
603 1         2 my $lvl =1;
604 1         5 my $chg ='';
605 1 50       18 local ($_, %dbm, *TRACK) if $opt !~/-\$/i;
606 1 50       5 if ($opt !~/-\$/i) {
607 1         4 Echo('FileTrack',$opt,@_);
608 1         2 $opt =$opt ."-\$";
609 1 0 33     124 dbmopen(%dbm, "$dst/FileTrack", 0666)
    50          
610             && open(TRACK,">>$dst/FileTrack.log") || croak(($Language =~/ru/i ?'⨥' :'Opening')." '$dst/FileTrack': $!");
611 1         7216 $dst =$dst ."/" .StrTime('yyyy-mm-dd_hh_mm_ss');
612 1 50   0   17 $sub =sub{1} if !$sub;
  0         0  
613 1         2 $lvl =0;
614             }
615 1         12 foreach (FileGlob("$src/*")) {
616 1         10 my @stat =stat;
617 1 50       6 my @nme =(/^(.*)[\/\\]([^\/\\]+)$/ ? ($1,$2) : ('',''));
618 1 50 33     30 if (@stat ==0 && ($opt =~/[^!i]*i/i || ($^O eq 'MSWin32' && /[\?]/i))) {next} # bug in stat!
  0 50 33     0  
  1 50 0     518  
    0          
    0          
    0          
619 0         0 elsif (@stat ==0) {croak(($Language =~/ru/i ?'㤠祭' :'Failure')." stat('$_'): $!"); undef($_)}
620 0         0 elsif ($stat[2] & 0040000 && $opt =~/!.*d/i) {}
621 0         0 elsif (!&$sub(\@stat,@nme)) {next}
622             elsif (!defined($_)) {return('')} # err stop: undef($_)
623 0 0 0     0 my $crc =$stat[2] & 0040000 || $opt !~/[^!]*t/i ? 0 : FileCRC($_);
624 0 0 0     0 my $tst =!$dbm{$_} ? 'I'
    0          
    0          
    0          
625             :$dbm{$_} !~/^([\d]+)\t([\d]+)$/ ? '?'
626             :$1 != $stat[9] && $opt !~/!.*t/i ? 'U'
627             :$2 != $crc ? 'C'
628             :undef;
629 0 0       0 if ($tst) {
630 0 0 0     0 if (($opt =~/!.*c/i) || ($stat[2] & 0040000)) {} # bug in win95 xcopy!
  0 0       0  
    0          
631 0         0 elsif (eval {FileCopy('-d',$_,$dst)}) {}
632 0         0 elsif ($opt =~/[^!i]*i/i) {next}
633             else {croak('FileTrack(' .join(', ',@_) ."): $@")}
634 0         0 $chg =1;
635 0         0 print TRACK StrTime(), "\t$tst\t$_\t",StrTime($stat[9]),"\t$crc\t$dst/$nme[1]\n";
636 0         0 $dbm{$_} =$stat[9] ."\t" .$crc;
637             }
638 0 0 0     0 if ($stat[2] & 0040000 && $opt !~/!.*r/i) { # no recurse: $_[0]->[2] =0
639 0   0     0 $chg =FileTrack($opt, "$src/$nme[1]", "$dst/$nme[1]", $sub) || $chg;
640 0 0       0 defined($_) || return(0);
641             }
642             }
643 0 0       0 if (!$lvl) {
644 0         0 foreach (keys(%dbm)) {
645 0 0       0 next if -e $_;
646 0 0       0 my ($tme,$crc) =$dbm{$_} !~/^([\d]+)\t([\d]+)$/ ? (0,0) : ($1,$2);
647 0         0 print TRACK StrTime(), "\tD\t$_\t",StrTime($tme),"\t$crc\n";
648 0         0 delete($dbm{$_});
649             }
650 0 0 0     0 dbmclose(%dbm)
    0          
651             && close(TRACK) || croak(($Language =~/ru/i ?'⨥' :'Closing')." '$dst/FileTrack': $!");
652 0 0       0 return(-d $dst ? $dst : '') if $chg;
    0          
653             }
654             $chg
655 0         0 }, ''}
656            
657             ###
658             sub FileWrite {
659 6     6 1 318 Try eval { local $ErrorDie =2;
  6         11  
660 6 50       21 my $opt =($_[0] =~/^\-/i ? shift : ''); # 'b'inary
661 6         11 my $file =shift;
662 6         14 Echo("FileWrite",$file);
663 6         15 local *OUT;
664 6 0       23937 open(OUT, ">$file") || croak(($Language =~/ru/i ?'⨥' :'Opening')." '>$file': $!");
    50          
665 6 50       30 if ($opt=~/b/i) {
666 0         0 binmode(OUT);
667 0 0       0 print(OUT @_) || croak(($Language =~/ru/i ?'' :'Writing')." '>$file': $!");
    0          
668             }
669             else {
670 6         16 foreach my $row (@_) {
671 22 0 33     198 !defined($row) || print(OUT $row, "\n") || croak(($Language =~/ru/i ?'' :'Writing')." '>$file': $!");
    50          
672             }
673             }
674 6 0       329 close(OUT) || croak(($Language =~/ru/i ?'⨥' :'Closing')." '>$file': $!");
    50          
675             },0}
676            
677             ###
678             sub FTPCmd {
679 0     0 1 0 my ($host,$usr,$passwd,$cmd);
680 0 0       0 if (ref($_[0])) {
681 0         0 foreach my $k (keys(%{$_[0]})) {
  0         0  
682 0 0       0 if ($k =~/^-*(host|srv|s$)/i) {$host =$_[0]->{$k}}
  0 0       0  
  0 0       0  
683 0         0 elsif ($k =~/^-*(user|usr|u$)/i) {$usr =$_[0]->{$k}}
684             elsif ($k =~/^-*(passwd|psw|p$)/i) {$passwd =$_[0]->{$k}}
685             }
686 0         0 shift;
687             }
688             else {
689 0         0 ($host,$usr,$passwd,$cmd)=(shift,shift,shift,shift)
690             }
691 0         0 Echo('FTPCmd',$host,$usr,$cmd,@_);
692 0         0 eval { local $ErrorDie =2;
  0         0  
693 0   0     0 my $ftp =eval("use Net::FTP; Net::FTP->new(\$host);") || croak("FTP $host: $@");
694 0 0       0 $ftp->login($usr, $passwd) || ($ftp->close, croak("FTP '${usr}\@${host}': $@"));
695 0 0       0 if ($cmd =~/^ascii|bin|ebcdic|byte/) {
696 0         0 $cmd =~s/^bin$/binary/;
697 0 0       0 eval("\$ftp->$cmd") || ($ftp->close, croak("FTP ${usr}\@${host} $cmd: $@"));
698 0         0 $cmd =shift;
699             }
700 0 0       0 my @ret = ref($cmd) eq 'CODE' ? &$cmd($ftp) : eval("\$ftp->$cmd(\@_)");
701 0         0 $ftp->close;
702 0 0       0 ($cmd =~/dir|ls/ ? $@ : !$ret[0]) && croak("FTP ${usr}\@${host} $cmd(".join(', ',@_)."): $@");
    0          
703 0 0       0 }; if ($@) {@ret =(); TryEnd()}
  0         0  
  0         0  
704 0 0       0 $cmd =~/dir|ls/ ? @ret : $ret[0];
705             }
706            
707             ###
708             sub GUIMsg {
709 0     0 1 0 Try eval { local $ErrorDie =2;
  0         0  
710 0 0       0 my $title = @_ >1 ? shift : '';
711 0 0       0 return(0) if !$Interact;
712 0 0       0 if (!$GUI) {map {Echo($_)} CPTranslate('ansi','oem',@_); return(Pause())};
  0         0  
  0         0  
  0         0  
713 0 0 0     0 my $eu =($] >=5.008) && !eval('${^ENCODING}') ? eval('use POSIX; POSIX::setlocale(POSIX::LC_CTYPE)=~/\\.([^.]+)$/ ? "cp$1" : undef') : undef;
714 0 0       0 $eu && eval("use encoding $eu, STDIN=>undef, STDOUT=>undef");
715 0         0 eval("use strict; use Tk");
716 0         0 my $main = new MainWindow (-title => $title);
717 0         0 $main->Label(-text => "\n" .join("\n", @_) ."\n"
718             ,-font => "System"
719             )->pack(-fill => 'x');
720 0     0   0 $main->Button(-text => ($Language =~/ru/i ?'' :'Close')
721             ,-font => 'System'
722             ,-command => sub{$main->destroy}
723 0 0       0 )->pack->focus();
724 0     0   0 $main->bind('Tk::Button',''
725             ,sub{my $r =$main->focusCurrent->cget('-command');
726 0 0       0 $r =~/array/i ? &{$$r[0]} : &$r });
  0         0  
  0         0  
727 0     0   0 $main->bind('',sub{$main->destroy});
  0         0  
728 0     0   0 $main->bind('',sub{$main->focusForce});
  0         0  
729 0         0 $main->grabGlobal;
730 0         0 $main->focusForce;
731 0         0 $main->update();
732 0         0 $main->geometry('+'.int(($main->screenwidth() -$main->width())/2.2)
733             .'+'.int(($main->screenheight() -$main->height())/2.2));
734 0 0       0 $eu && eval("no encoding");
735 0         0 eval("MainLoop()");
736             },0}
737            
738             ###
739             sub NetUse {
740 0     0 1 0 Try eval { local $ErrorDie =2;
  0         0  
741 0         0 my ($d)=@_;
742 0 0 0     0 if (!$_[1] || $_[1] =~/^\/d/i) {eval {`net use $d /delete`}; return(1)}
  0 0 0     0  
  0 0 0     0  
  0         0  
  0         0  
743             elsif (!$ENV{OS} || $ENV{OS} =~/Windows_95/i) {return(Run('net','use',@_,'/Yes'))}
744 0         0 elsif ( $ENV{OS} && $ENV{OS} =~/Windows_NT/i) {
745 0         0 Echo('net','use',@_); my $r =$_[1];
  0         0  
746 0         0 if (0 && $d =~/^\w:*$/i && WScript('Network')) {WScript('Network')->RemoveNetworkDrive($d); $r =WScript('Network')->MapNetworkDrive(@_) ? 0 : Win32::OLE->LastError}
  0         0  
747 0         0 else {eval {`net use $d /delete & net use $d $r 2>&1`}; $r =$?>>8}
  0         0  
748 0 0       0 croak(join(' ','net','use',@_).": $r") if $r; return(!$r)
  0         0  
749             }
750 0         0 else {eval {`net use $d /delete`}; Run('net','use',@_)}
  0         0  
751             },0}
752            
753             ###
754             sub OLECreate {
755 0     0 1 0 Try eval { local $ErrorDie =2;
  0         0  
756 0         0 eval('use Win32::OLE');
757 0 0       0 Win32::OLE->new(@_) ||croak('OLECreate(' .join(' ',@_) .') -> ' .Win32::OLE->LastError());
758             },undef}
759            
760             ###
761             sub OLEGet {
762 0     0 1 0 Try eval { local $ErrorDie =2;
  0         0  
763 0         0 eval('use Win32::OLE');
764 0 0       0 Win32::OLE->GetObject(@_) ||croak('OLEGet(' .join(' ',@_) .') -> ' .Win32::OLE->LastError());
765             },undef}
766            
767             ###
768             sub OLEIn {
769 0 0 0 0 1 0 eval('use Win32::OLE'); Win32::OLE::in(ref($_[0]) ? $_[0] : (OLEGet(@_)||OLECreate(@_)));
  0         0  
770             }
771            
772             ###
773             sub OrArgs {
774 0 0   0 1 0 my $s =ref($_[0]) ? shift
    0          
775             :index($_[0], '-') ==0 ? eval('sub{' .shift(@_) .' $_}')
776             :eval('sub{' .shift(@_) .'($_)}');
777 0         0 local $_;
778 0 0       0 foreach (@_) {return $_ if &$s($_)};
  0         0  
779             undef
780 0         0 }
781            
782             ###
783             sub Pause {
784 7     7 1 562 Try eval { local $ErrorDie =2;
  7         19  
785 7 0       28 if (@_) {print(join(' ',@_))}
  7 50       37  
  0         0  
786             else {print(($Language =~/ru/i ?'' :'Press')." 'Enter'...")}
787 7 50       24 return('') if !$Interact;
788 7         75 my $r =;
789 7         18 chomp($r); $r
  7         22  
790             },''}
791            
792             ###
793             sub Platform {
794 13     13 1 1573 Try eval { local $ErrorDie =2;
  13         40  
795 13 100       427 if ($_[0] =~/^os$/i) {
    100          
    50          
    100          
    100          
    100          
    100          
    100          
    100          
    100          
    100          
    100          
    50          
796 1 50 0     10 $ENV{OS}
    50          
797             ? $ENV{OS}
798             : $^O eq 'MSWin32'
799             ? eval('use Win32::TieRegistry; my $v =$$Registry{\'LMachine\\Software\\Microsoft\\Windows\\CurrentVersion\\\\Version\'}; $v =~s/ /_/ig; $v') || 'Windows_95'
800             : $^O # 'Dos'
801             }
802             elsif ($_[0] =~/^osname$/i) {
803 1 50 0     3542 ($^O eq 'MSWin32'
    50 33        
    50 33        
804             ? eval('use Win32::TieRegistry;$$Registry{\'LMachine\\Software\\Microsoft\\Windows\\CurrentVersion\\\\Version\'}') ||''
805             : '')
806             || (`\%COMSPEC\% /c ver` =~/\n*([^\n]+)\n*/i ? $1 : '')
807             || $ENV{OS} || $^O
808             }
809             elsif ($_[0] =~/^win32$/i) {
810 0 0 0     0 $^O eq 'MSWin32' ? ($ENV{windir} || Platform('windir')) : ''
811             }
812             elsif ($_[0] =~/^ver/i) {
813 1   33     9931 my $v =
814             ($^O eq 'MSWin32'
815             ? eval('use Win32::TieRegistry; my $v =
816             ($$Registry{\'LMachine\\Software\\Microsoft\\Windows\\CurrentVersion\\\\VersionNumber\'} || $$Registry{\'LMachine\\Software\\Microsoft\\Windows NT\\CurrentVersion\\\\CurrentVersion\'} || \'\')
817             .".".
818             ($$Registry{\'LMachine\\Software\\Microsoft\\Windows\\CurrentVersion\\\\SubVersionNumber\'} || $$Registry{\'LMachine\\Software\\Microsoft\\Windows NT\\CurrentVersion\\\\CurrentBuildNumber\'} || \'\')
819             ; $v =~s/ //ig; $v')
820             : '')
821             || (`\%COMSPEC\% /c ver` =~/(Version|)\s*([^ \]]+)/im ? $2 : '');
822 1 50 0     69 (@_ >1 ? [split(/\./,$v)]->[$_[1]] ||'' : $v);
823             }
824             elsif ($_[0] =~/^(patch)/i) {
825 1 50 0     19 $^O eq 'MSWin32'
826             ? eval('use Win32::TieRegistry; $$Registry{\'LMachine\\Software\\Microsoft\\Windows\\CurrentVersion\\\\CSDVersion\'} || $$Registry{\'LMachine\\Software\\Microsoft\\Windows NT\\CurrentVersion\\\\CSDVersion\'}') || ''
827             : ''
828             }
829             elsif ($_[0] =~/^lang$/i) {
830 1 50       5869 `\%COMSPEC\% /c dir c:\\` =~/᢮$/i ? 'ru' : '';
831             }
832             elsif ($_[0] =~/^prodid$/i) {
833 1 50 0     18 $^O eq 'MSWin32'
834             ? eval('use Win32::TieRegistry;$$Registry{\'LMachine\\Software\\Microsoft\\Windows\\CurrentVersion\\\\ProductId\'} || $$Registry{\'LMachine\\Software\\Microsoft\\Windows NT\\CurrentVersion\\\\ProductId\'}') || ''
835             : ''
836             }
837             elsif ($_[0] =~/^name$/i) {
838             $ENV{COMPUTERNAME}
839             ? lc($ENV{COMPUTERNAME})
840             : $^O eq 'MSWin32'
841 1 50 0     4893 ? eval{Win32::NodeName()} ||lc(eval('use Win32::TieRegistry; $$Registry{\'LMachine\\\\System\\\\CurrentControlSet\\\\Control\\\\ComputerName\\\\ComputerName\\\\\\\\ComputerName\'}'))
    50          
    50          
842             : `net config` =~/(Computer name|)\s*\\*([^ ]+)$/im
843             ? lc($2)
844             : Platform('host');
845             }
846             elsif ($_[0] =~/^hostdomain$/i) { # [gethostbyname('')]->[0] =~/[^\.]*\.(.*)/ ? $1 : ''
847 1     1   5 eval('use Net::Domain;Net::Domain::hostdomain')
  1         1  
  1         25  
  1         50  
848             }
849             elsif ($_[0] =~/^host$/i) { # [gethostbyname('')]->[0]
850 1     1   1501 my $r =eval('use Sys::Hostname;hostname');
  1     1   2160  
  1         65  
  1         8  
  1         1  
  1         49  
  2         263  
851 1 50   1   1214 index($r,'.') <0 ? ($r .'.' .eval('use Net::Domain;Net::Domain::hostdomain')) : $r
  1     1   14770  
  1         49  
  1         5  
  1         2  
  1         30  
  2         215  
852             }
853             elsif ($_[0] =~/^domain|userdomain$/i) {
854 1 50       11 $ENV{USERDOMAIN} || ($^O eq 'MSWin32' ? Win32::DomainName() :'')
    50          
855             }
856             elsif ($_[0] =~/^user$/i) {
857             getlogin()
858 1 50 0     173 ||($^O eq 'MSWin32' ? eval{Win32::LoginName()}
    50 33        
      33        
      33        
859             || lc(eval("use Win32::TieRegistry; \$\$Registry{'LMachine\\\\System\\\\CurrentControlSet\\\\Control\\\\\\\\Current User'}"))
860             || (`net config` =~/(User name|짮⥫)\s*([^ ]+)$/im ? $2 : '')
861             : '')
862             ||$ENV{USERNAME} ||$ENV{LOGNAME} ||''
863             }
864 0         0 elsif ($_[0] =~/^windir$/i) {
865 1 50       14 return $ENV{windir} if $ENV{windir};
866 1 50       17 return '' if $^O ne 'MSWin32';
867 0         0 eval('use Win32::TieRegistry');
868 0 0       0 $Registry->{'LMachine\\Software\\Microsoft\\Windows NT\\CurrentVersion\\\\SystemRoot'}
869             || $Registry->{'LMachine\\Software\\Microsoft\\Windows\\CurrentVersion\\\\SystemRoot'};
870             }
871             else {''}
872             },''}
873            
874             ###
875             sub Print {
876 18 50   18 1 53 if ($Print) {&$Print(@_)}
  0         0  
877 18         67 else { print(join(' ',@_), "\n");
878 18 50       70 print LOG join(' ',StrTime(),@_), "\n" if $FileLog;
879             }
880             }
881            
882             ###
883             sub Registry {
884 0     0 1 0 Try eval { local $ErrorDie =2;
  0         0  
885 0 0       0 my $opt =($_[0] =~/^\-/i ? shift : '');
886 0 0       0 my $dlm =$opt =~/\-([\|\/\\])/ ? $1 : '\\';
887 0         0 my $key =shift;
888 0         0 eval("use Win32::TieRegistry; \$Registry->Delimiter(\$dlm)");
889 0 0       0 return ($$Registry{$key}) if @_ ==0;
890 0 0       0 my ($type)=@_ >1 ? shift : '';
891 0 0 0     0 return(delete($$Registry{$key})) if @_ >0 && !defined($_[0]);
892 0         0 my ($val) =@_;
893 0 0 0     0 if ($type && $type !~/^REG_/i && $val =~/^REG_/i) {$val =$type; $type =$_[0]};
  0   0     0  
  0         0  
894 0         0 my ($k, $h, $n);
895 0         0 $k =rindex($key,"$dlm$dlm");
896 0 0       0 if ($k<0) {$k =rindex($key,$dlm); $n =substr($key, $k +1)}
  0         0  
  0         0  
  0         0  
897             else {$n =substr($key, $k +2)}
898 0         0 $key =substr($key, 0, $k);
899 0         0 $k =$key;
900 0         0 while(!ref($$Registry{$k})) { # while(!$$Registry{$k})) {
901 0 0       0 $h ={substr($k, rindex($k,$dlm)+1)=>($h ? $h : {})};
902 0         0 $k = substr($k, 0, rindex($k,$dlm));
903             }
904 0 0       0 $$Registry{$k} =$h if $h;
905 0 0       0 if ($type) {$$Registry{$key}->SetValue($n,$val,$type)}
  0         0  
  0         0  
906             else {$$Registry{$key .$dlm .$dlm .$n} =$val}
907             },''}
908            
909             ###
910             sub Run {
911 1     1 1 150 Try eval { local $ErrorDie =2;
  1         4  
912 1         9 Echo(@_);
913 1 50       6 if (ref($_[$#_]) eq 'CODE') {
914 0         0 my $sub =pop;
915 0         0 local (*OUT, *OLDIN);
916 0 0 0     0 open(OLDIN,'<&STDIN') && pipe(STDIN,OUT) || croak(join(' ',@_) ." : $?");
917 0     0   0 FileHandle(\*OUT, sub{$|=1; &$sub()});
  0         0  
  0         0  
918 0         0 system(@_);
919 0         0 close(OUT); open(STDIN,'<&OLDIN');
  0         0  
920             }
921             else {
922 1         2859 system(@_)
923             }
924 1         23 my $r =$?>>8; #($?>>8 || $!);
925 1 50       489 croak(join(' ',@_).": $r") if $r;
926 0         0 !$r
927             },0}
928            
929             ###
930             sub RunInf {
931 0     0 1 0 Try eval { local $ErrorDie =2;
  0         0  
932 0         0 my ($f, $s, $b) =@_;
933 0 0       0 $s ="DefaultInstall" if !defined($s);
934 0 0       0 $b =128 if !defined($b);
935 0         0 eval("use Win32::TieRegistry");
936 0   0     0 my $cmd =$Registry->{"Classes\\inffile\\shell\\Install\\command\\\\"} || 'rundll32.exe setupx.dll,InstallHinfSection DefaultInstall 132 %1';
937 0 0       0 $cmd =~s/%SystemRoot%/$ENV{windir}/ if $ENV{windir};
938 0         0 $cmd =~s/ DefaultInstall / $s /i;
939 0         0 $cmd =~s/ 132 / $b /i;
940 0         0 $cmd =~s/%1/$f/i;
941 0         0 $cmd
942             },0}
943            
944             ###
945             sub RunKbd {
946 0     0 1 0 Try eval { local $ErrorDie =2;
  0         0  
947 0         0 eval("use Win32::GuiTest");
948 0         0 my ($wt,$ws,$kt,$ks) =(60,'',1);
949 0 0       0 if (!defined($_[0])) {shift; $ws=shift}
  0 0       0  
  0         0  
  0         0  
950 0         0 elsif ($_[0] =~/^[\d]+$/) {($wt,$ws) =(shift,shift)}
951             else {$ws =shift}
952 0 0       0 if (!@_) {}
  0 0       0  
953 0         0 elsif (@_ <2) {$ks =shift}
954             else {($kt,$ks) =(shift,shift)}
955 0   0     0 Echo(CPTranslate('ansi','oem','RunKbd',$wt,"'$ws'",$kt,"'" .($ks||'') ."'"));
956 0 0       0 if ($ws ne '') {
957 0         0 my @wnd;
958 0         0 for (my $i =0; $i <$wt; $i++) {
959 0         0 local $^W =0;
960 0         0 @wnd =();
961 0         0 @wnd =eval {Win32::GuiTest::FindWindowLike(undef,$ws)};
  0         0  
962 0 0 0     0 last if ((!defined($ks) || $ks ne '') ? @wnd : !@wnd);
    0          
963 0 0 0     0 print "." if $Echo && $Interact;
964 0         0 sleep(1);
965             }
966 0 0 0     0 if ( @wnd && defined($ks) && $ks eq '') {Echo('.timeout'); return 0}
  0 0 0     0  
  0 0 0     0  
  0 0 0     0  
967 0         0 elsif (!@wnd && defined($ks) && $ks eq '') {Echo('.ok'); return 1}
  0         0  
968 0         0 elsif ( @wnd >1) {croak("RunKbd: several windows like '" .CPTranslate('ansi','oem',"$ws': " .join("',",map {"$_:'" .Win32::GuiTest::GetWindowText($_)} @wnd)) ."'")}
  0         0  
969             elsif (!@wnd) {croak("RunKbd: not found " .CPTranslate('ansi','oem',"'$ws'"))};
970 0         0 Win32::GuiTest::SetFocus($wnd[0]);
971 0         0 Echo('. ' .$wnd[0] .":'" .CPTranslate('ansi','oem',Win32::GuiTest::GetWindowText($wnd[0])) ."'");
972 0 0       0 if (!defined($ks)) {return $wnd[0]}
  0         0  
973             }
974 0         0 sleep($kt);
975 0 0 0     0 !defined($ks) || $ks eq '' || Win32::GuiTest::SendKeys($ks) || 1;
      0        
976             },0}
977            
978             ###
979             sub SMTPSend {
980 0     0 1 0 Try eval { local $ErrorDie =2;
  0         0  
981 0         0 my $host =shift;
982 0 0       0 my $from =$_[0] !~/:/ ? shift : undef;
983 0 0       0 my $to =ref($_[0]) ? shift : undef;
984 0 0 0     0 foreach my $r (@_) {last if $from && $to;
  0         0  
985 0 0 0     0 if (ref($r)) {$to =$r; $r ='To:'.join(',',@$r)}
  0 0 0     0  
  0 0       0  
  0         0  
986 0         0 elsif (!$from && $r=~/^(from|sender):(.*)/i) {$from =$2}
987             elsif (!$to && $r=~/^to:(.*)/i) {$to =[split /,/,$1]}
988             }
989 0         0 Echo('SMTPSend',"$host, $from -> ".join(',',@$to));
990 0         0 my $smtp =eval("use Net::SMTP; Net::SMTP->new(\$host)");
991 0 0       0 $@ && croak($@);
992 0 0       0 !$smtp && croak("SMTP Host $host");
993 0 0       0 $smtp->mail($from) ||croak("SMTP From: $from");
994 0 0       0 $smtp->to(@$to) ||croak("SMTP To: ".join(', ',@$to));
995 0 0       0 $smtp->data(join("\n",@_)) ||croak("SMTP Data");
996 0 0       0 $smtp->dataend() ||croak("SMTP DataEnd");
997 0         0 $smtp->quit;
998 0         0 1
999             },0}
1000            
1001             ###
1002             sub StrTime {
1003 1 0 33 1 1 18 my $msk =@_ ==0 || $_[0] =~/^\d+$/i ? ($Language =~/ru/i ? 'dd.mm.yy hh:mm:ss' : 'yyyy-mm-dd hh:mm:ss') : shift;
    50          
1004 1 50       5 $msk ='yyyymmddhhmmss' if !$msk;
1005 1 0       180 my @tme =@_ ==0 ? localtime(time) : @_ ==1 ? localtime($_[0]) : @_;
    50          
1006 1         14 $msk =~s/yyyy/sprintf('%04u',$tme[5] +1900)/ie;
  1         11  
1007 1 50       6 $tme[5] >=100 ? $msk =~s/yy/sprintf('%04u',$tme[5] +1900)/ie
  0         0  
1008 0         0 : $msk =~s/yy/sprintf('%02u',$tme[5])/ie;
1009 1         8 $msk =~s/mm/sprintf('%02u',$tme[4]+1)/e;
  1         10  
1010 1         5 $msk =~s/dd/sprintf('%02u',$tme[3])/ie;
  1         5  
1011 1         4 $msk =~s/hh/sprintf('%02u',$tme[2])/ie;
  1         5  
1012 1         5 $msk =~s/mm/sprintf('%02u',$tme[1])/ie;
  1         5  
1013 1         5 $msk =~s/ss/sprintf('%02u',$tme[0])/ie;
  1         5  
1014 1         5 $msk
1015             }
1016            
1017             ###
1018             sub Try (@) {
1019 43     43 1 9080 my $ret;
1020 43         118 local ($TrySubject, $TryStage) =('','');
1021 43         57 { local $ErrorDie =2;
  43         53  
1022 43 50 66     311 $ret = @_ >1 && ref($_[0]) eq 'CODE' ? eval {&{$_[0]}} : $_[0];
  0         0  
  0         0  
1023             }
1024 43 100       96 if (!$@) {$ret}
  37         939  
1025             else {
1026 6 50       58 my $err =$@ =$Error =$TrySubject .($TryStage eq '' ? '' : ": $TryStage:\n") .$@;
1027 6 50       32 $ret =ref($_[$#_]) eq 'CODE' ? &{$_[$#_]}() : $_[$#_];
  0         0  
1028 6 50       19 $@ ="$err\n$@" unless $@ eq $err;
1029 6 0 0     68 if ($ErrorDie) {$^S || $ErrorDie ==2 ? die($err) : Die($err)}
  0 50 33     0  
  6 50       581  
1030             elsif ($Echo && ref($_[$#_]) ne 'CODE') {warn("Error: $@")}
1031             $ret
1032 6         241 }
1033             }
1034            
1035             ###
1036             sub TryEnd {
1037 0 0 0 0 0 0 return(0) if !$@ && !@_;
1038 0         0 my $ert =@_;
1039 0 0       0 my $err =$Error =(@_ ? join(' ',@_) : $@);
1040 0 0 0     0 if ($ErrorDie) {$^S || $ErrorDie ==2 ? ($ert ? croak($err) : die($err)) : Die($err)}
  0 0       0  
  0 0       0  
    0          
1041 0 0       0 elsif ($Echo) {$err ="Error: $err"; ($ert ? carp($err) : warn($err))}
1042             0
1043 0         0 }
1044            
1045             ###
1046             sub TryHdr {
1047 0 0   0 1 0 $TrySubject =$_[0] if defined($_[0]);
1048 0 0       0 $TryStage =$_[1] if defined($_[1]);
1049 0 0       0 $Echo && Print($TrySubject.($TryStage ne '' ? ": $TryStage" : $TryStage)."...");
    0          
1050 0         0 ''
1051             }
1052            
1053             ###
1054             sub UserEnvInit {
1055 0     0 1 0 Try eval { local $ErrorDie =2;
  0         0  
1056 0 0       0 return(0) if $^O ne 'MSWin32';
1057 0 0 0     0 my $opt =shift || 'nh'; $opt ='nhy' if $opt =~/^y$/i;
  0         0  
1058 0         0 my $os =Platform('os');
1059            
1060 0 0 0     0 if ($opt =~/n/i && (lc($os) ne 'windows_nt')){
1061 0         0 foreach my $e (['OS'=>$os],['COMPUTERNAME'=>Platform('name')],['USERNAME'=>Platform('user')]) {
1062 0 0 0     0 (!$ENV{$e->[0]} || $opt =~/y/i)
      0        
1063             && ($ENV{$e->[0]} =$e->[1])
1064             && Run('winset',$e->[0] .'=' .$e->[1])
1065             }
1066             }
1067 0 0       0 return($ENV{USERNAME}) if $opt !~/h/i;
1068            
1069 0         0 $os =lc($os);
1070 0   0     0 my $d = OrArgs('-d',@_,'c:\\Home') ||return(0);
1071 0   0     0 my $u = $ENV{USERNAME} ||Platform('user');
1072 0         0 my $du= $d .'\\' .ucfirst(lc($u));
1073 0         0 my $dw= OrArgs('-d',"$d\\Work",$d);
1074 0 0       0 if (!-d $du) {
1075 0 0       0 FileMkDir($du, 0700) ||return(0);
1076 0 0       0 if ($os eq 'windows_nt') {
1077 0         0 Run('cacls',$du,'/E','/C','/P',"$ENV{USERDOMAIN}\\$u:F");
1078 0         0 eval('use Win32::FileSecurity');
1079 0         0 my %acl; Win32::FileSecurity::Get($du,\%acl);
  0         0  
1080 0         0 foreach my $k (keys(%acl)) {
1081 0 0       0 if ($k !~/\\($u|System||Administrator|)/i)
  0 0       0  
1082             {Run('cacls',$du,'/E','/C','/R','"'.($k =~/ [^\\]*\\(.*)/ ? $1 : $k).'"')}
1083             }
1084             }
1085             }
1086 0   0     0 my $pu= $ENV{USERPROFILE} ||UserPath();
1087 0   0     0 $pu= eval{Win32::GetShortPathName($pu)} ||$pu;
1088 0 0 0     0 return(1) if $opt !~/y/i && (lc($ENV{HOME}||'?') eq lc($pu));
      0        
1089 0         0 my $ru='CUser\\Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\User Shell Folders\\\\';
1090 0 0 0     0 my $rp=$os ne 'windows_nt' && !Registry('LMachine\\Network\\Logon\\\\UserProfiles') ? $dw : $du;
1091 0         0 Registry($ru .'Personal',$rp);
1092 0         0 Registry($ru .'My Pictures',$rp .'\\My Pictures');
1093 0 0       0 $pu =~s/[\\]/\//g if $os eq 'windows_nt';
1094 0         0 foreach my $e (['HOME'=>$pu], ['HOMEDOCS'=>$rp]) {
1095 0 0 0     0 next if lc($ENV{$e->[0]}||'?') eq lc($e->[1]);
1096 0         0 $ENV{$e->[0]} =$e->[1];
1097 0 0       0 if ($os eq 'windows_nt'){Run('setx',$e->[0],$e->[1])}
  0         0  
  0         0  
1098             else {Run('winset',$e->[0] .'=' .$e->[1])}
1099             }
1100 0         0 1;
1101             },0}
1102            
1103             ###
1104             sub UserPath {
1105 1     1 1 79 Try eval { local $ErrorDie =2;
  1         2  
1106 1   50     23 my ($u,$pd) =($_[0]||'', $_[1]||'');
      50        
1107 1 50 50     5 if ($^O ne 'MSWin32') {($ENV{HOME} || '') .($pd ? '/' .$pd :'')}
  1 50       15  
1108             else {
1109 0           my %syn =('application data'=>'AppData'
1110             ,'home'=>'Personal'
1111             ,'start menu\\programs'=>'Programs'
1112             ,'start menu/programs'=>'Programs'
1113             ,'start menu\\programs\\startup'=>'Startup'
1114             ,'start menu/programs/startup'=>'Startup');
1115 0   0       $pd =$syn{lc($pd)} ||$pd;
1116 0           eval 'use Win32::TieRegistry';
1117 0           my $ha ='LMachine\\Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders\\\\Common ';
1118 0 0         my $hu =($u =~/^\.*default$/i
1119             ? 'Users\\.DEFAULT\\Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders\\\\'
1120             : 'CUser\\Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders\\\\');
1121 0 0 0       my $e =(!defined($pd) || $pd eq '') ? ($pd ='Desktop') : 0;
1122 0 0 0       my $r =($u =~/^all$/i
      0        
1123             ? $Registry->{$ha .$pd} ||$Registry->{$hu .$pd}
1124             : $Registry->{$hu .$pd}
1125             || ($u =~/^\.*default$/i && lc($pd) eq 'start menu'
1126             ? $Registry->{$hu .($e =$pd ='Programs')} : '')
1127             || $Registry->{$ha .$pd});
1128 0           $r =~s/\s*$//i;
1129 0 0         !$e ? $r : $r =~/^(.*)[\\\/][^\\\/]*$/i ? $1 : '';
    0          
1130             }
1131             },''}
1132            
1133             ###
1134             sub WMIService {
1135 0     0 1   Try eval { local $ErrorDie =2;
  0            
1136 0           my $h =OLECreate('WbemScripting.SWbemLocator');
1137 0           $h->ConnectServer(@_)
1138             },undef}
1139            
1140             ###
1141             sub WScript {
1142 0     0 1   Try eval { local $ErrorDie =2;
  0            
1143 0 0         my $u =!defined($_[0]) ? shift : 1;
1144 0           my $n =shift;
1145 0 0 0       return($WScript{$n}) if $u && exists($WScript{$n});
1146 0 0         $WScript{$n} =undef if $u;
1147 0 0         my $o =OLECreate(($n eq 'FSO' ? 'Scripting.FileSystemObject' : "WScript.$n"), @_);
1148 0 0         $u ? ($WScript{$n} =$o) : $o;
1149             },undef}
1150