]> git.p6c8.net - devedit.git/blob - modules/Tool.pm
Simplified check_path() a little bit
[devedit.git] / modules / Tool.pm
1 package Tool;
2
3 #
4 # Dev-Editor - Module Tool
5 #
6 # Some shared sub routines
7 #
8 # Author: Patrick Canterino <patrick@patshaping.de>
9 # Last modified: 2005-05-07
10 #
11
12 use strict;
13
14 use vars qw(@EXPORT);
15
16 use CGI qw(redirect
17 escape
18 virtual_host
19 https);
20
21 use Cwd qw(abs_path);
22 use File::Spec;
23
24 ### Export ###
25
26 use base qw(Exporter);
27
28 @EXPORT = qw(check_path
29 clean_path
30 devedit_reload
31 dos_wildcard_match
32 encode_html
33 equal_url
34 file_name
35 mode_string
36 multi_string
37 upper_path);
38
39 # check_path()
40 #
41 # Check if a virtual path is above a virtual root directory
42 # (currently no check if the path exists - check otherwise!)
43 #
44 # Params: 1. Virtual root directory
45 # 2. Virtual path to check
46 #
47 # Return: Array with the physical and the cleaned virtual path;
48 # false, if the submitted path is above the root directory
49
50 sub check_path($$)
51 {
52 my ($root,$path) = @_;
53
54 # Clean root path
55
56 $root = abs_path($root);
57 $root = File::Spec->canonpath($root);
58
59 $path =~ tr!\\!/!;
60 $path =~ s!^/+!!;
61 $path = $root.'/'.$path;
62
63 # We extract the last part of the path and create the absolute path
64
65 my $first = upper_path($path);
66 $first = File::Spec->canonpath($first);
67 $first = abs_path($first);
68
69 my $last = file_name($path);
70
71 if(-d $first.'/'.$last && not -l $first.'/'.$last)
72 {
73 $first = abs_path($first.'/'.$last);
74 $last = '';
75 }
76
77 $path = File::Spec->canonpath($first.'/'.$last);
78
79 # Check if the path is above the root directory
80
81 return if(index($path,$root) != 0);
82
83 # Create short path name
84
85 my $short_path = substr($path,length($root));
86 $short_path =~ tr!\\!/!;
87 $short_path = '/'.$short_path if($short_path !~ m!^/!);
88 $short_path = $short_path.'/' if($short_path !~ m!/$! && -d $path && not -l $path);
89
90 return ($path,$short_path);
91 }
92
93 # clean_path()
94 #
95 # Clean up a path logically and replace backslashes with
96 # normal slashes
97 #
98 # Params: Path
99 #
100 # Return: Cleaned path
101
102 sub clean_path($)
103 {
104 my $path = shift;
105 $path = File::Spec->canonpath($path);
106 $path =~ tr!\\!/!;
107
108 return $path;
109 }
110
111 # devedit_reload()
112 #
113 # Create a HTTP redirection header to load Dev-Editor
114 # with some other parameters
115 #
116 # Params: Hash Reference (will be merged to a query string)
117 # (optional)
118 #
119 # Return: HTTP redirection header (Scalar Reference)
120
121 sub devedit_reload(;$)
122 {
123 my $params = shift;
124
125 # Detect the protocol (simple HTTP or SSL encrypted HTTP)
126 # and check if the server listens on the default port
127
128 my $protocol = '';
129 my $port = '';
130
131 if(https)
132 {
133 # SSL encrypted HTTP (HTTPS)
134
135 $protocol = 'https';
136 $port = ':'.$ENV{'SERVER_PORT'} if($ENV{'SERVER_PORT'} != 443);
137 }
138 else
139 {
140 # Simple HTTP
141
142 $protocol = 'http';
143 $port = ':'.$ENV{'SERVER_PORT'} if($ENV{'SERVER_PORT'} != 80);
144 }
145
146 # The following code is grabbed from Template::_query of
147 # Andre Malo's selfforum (http://sourceforge.net/projects/selfforum/)
148 # and modified by Patrick Canterino
149
150 my $query = '';
151
152 if(ref($params) eq 'HASH')
153 {
154 $query = '?'.join ('&' =>
155 map {
156 (ref)
157 ? map{escape ($_).'='.escape ($params -> {$_})} @{$params -> {$_}}
158 : escape ($_).'='.escape ($params -> {$_})
159 } keys %$params
160 );
161 }
162
163 # Create the redirection header
164
165 my $header = redirect($protocol.'://'.virtual_host.$port.$ENV{'SCRIPT_NAME'}.$query);
166
167 return \$header;
168 }
169
170 # dos_wildcard_match()
171 #
172 # Check if a string matches against a DOS-style wildcard
173 #
174 # Params: 1. Pattern
175 # 2. String
176 #
177 # Return: Status code (Boolean)
178
179 sub dos_wildcard_match($$)
180 {
181 my ($pattern,$string) = @_;
182
183 # The following part is stolen from File::DosGlob
184
185 # escape regex metachars but not glob chars
186 $pattern =~ s:([].+^\-\${}[|]):\\$1:g;
187 # and convert DOS-style wildcards to regex
188 $pattern =~ s/\*/.*/g;
189 $pattern =~ s/\?/.?/g;
190
191 return ($string =~ m|^$pattern$|is);
192 }
193
194 # encode_html()
195 #
196 # Encode HTML control characters (< > " &)
197 #
198 # Params: String to encode
199 #
200 # Return: Encoded string
201
202 sub encode_html($)
203 {
204 my $string = shift;
205
206 $string =~ s/&/&amp;/g;
207 $string =~ s/</&lt;/g;
208 $string =~ s/>/&gt;/g;
209 $string =~ s/"/&quot;/g;
210
211 return $string;
212 }
213
214 # equal_url()
215 #
216 # Create URL equal to a file or directory
217 #
218 # Params: 1. HTTP root
219 # 2. Relative path
220 #
221 # Return: Formatted link (String)
222
223 sub equal_url($$)
224 {
225 my ($root,$path) = @_;
226 my $url;
227
228 $root =~ s!/+$!!;
229 $path =~ s!^/+!!;
230 $url = $root.'/'.$path;
231
232 return $url;
233 }
234
235 # file_name()
236 #
237 # Return the last part of a path
238 #
239 # Params: Path
240 #
241 # Return: Last part of the path
242
243 sub file_name($)
244 {
245 my $path = shift;
246 $path =~ tr!\\!/!;
247
248 unless($path =~ m!^/+$! || ($^O eq 'MSWin32' && $path =~ m!^[a-z]:/+$!i))
249 {
250 $path =~ s!/+$!!;
251 $path = substr($path,rindex($path,'/')+1);
252 }
253
254 return $path;
255 }
256
257 # mode_string()
258 #
259 # Convert a file mode number into a human readable string (rwxr-x-r-x)
260 # (also supports SetUID, SetGID and Sticky Bit)
261 #
262 # Params: File mode number
263 #
264 # Return: Human readable mode string
265
266 sub mode_string($)
267 {
268 my $mode = shift;
269 my $string = '';
270
271 # User
272
273 $string = ($mode & 00400) ? 'r' : '-';
274 $string .= ($mode & 00200) ? 'w' : '-';
275 $string .= ($mode & 00100) ? (($mode & 04000) ? 's' : 'x') :
276 ($mode & 04000) ? 'S' : '-';
277
278 # Group
279
280 $string .= ($mode & 00040) ? 'r' : '-';
281 $string .= ($mode & 00020) ? 'w' : '-';
282 $string .= ($mode & 00010) ? (($mode & 02000) ? 's' : 'x') :
283 ($mode & 02000) ? 'S' : '-';
284
285 # Other
286
287 $string .= ($mode & 00004) ? 'r' : '-';
288 $string .= ($mode & 00002) ? 'w' : '-';
289 $string .= ($mode & 00001) ? (($mode & 01000) ? 't' : 'x') :
290 ($mode & 01000) ? 'T' : '-';
291
292 return $string;
293 }
294
295 # multi_string()
296 #
297 # Create a Hash Reference containing three forms of a string
298 #
299 # Params: String
300 #
301 # Return: Hash Reference:
302 # normal => Normal form of the string
303 # html => HTML encoded form (see encode_html())
304 # url => URL encoded form
305
306 sub multi_string($)
307 {
308 my $string = shift;
309 my %multi;
310
311 $multi{'normal'} = $string;
312 $multi{'html'} = encode_html($string);
313 $multi{'url'} = escape($string);
314
315 return \%multi;
316 }
317
318 # upper_path()
319 #
320 # Remove the last part of a path
321 # (the resulting path contains a trailing slash)
322 #
323 # Params: Path
324 #
325 # Return: Truncated path
326
327 sub upper_path($)
328 {
329 my $path = shift;
330 $path =~ tr!\\!/!;
331
332 unless($path =~ m!^/+$! || ($^O eq 'MSWin32' && $path =~ m!^[a-z]:/+$!i))
333 {
334 $path =~ s!/+$!!;
335 $path = substr($path,0,rindex($path,'/')+1);
336 }
337
338 return $path;
339 }
340
341 # it's true, baby ;-)
342
343 1;
344
345 #
346 ### End ###

patrick-canterino.de