3 # Outputs HTML for a frame-based file chooser
5 @icon_map = ( "c", "text.gif",
16 require (-r './web-lib.pl' ? './web-lib.pl' : '../web-lib.pl');
18 %access = &get_module_acl();
20 # Work out root directory
21 if (!$access{'root'}) {
22 local @uinfo = getpwnam($remote_user);
23 $rootdir = $uinfo[7] ? $uinfo[7] : "/";
26 $rootdir = $access{'root'};
29 # Switch to correct Unix user
30 if (&supports_users()) {
31 if (&get_product_name() eq 'usermin') {
32 # Always run as Usermin login
33 &switch_to_remote_user();
37 $fileunix = $access{'fileunix'} || $remote_user;
38 @uinfo = getpwnam($fileunix);
40 ($(, $)) = ( $uinfo[3],
41 "$uinfo[3] ".join(" ", $uinfo[3],
42 &other_groups($uinfo[0])) );
43 ($>, $<) = ( $uinfo[2], $uinfo[2] );
48 &ReadParse(undef, undef, 1);
49 if ($gconfig{'os_type'} eq 'windows') {
50 # On Windows, chroot should be empty if not use, and default path
52 if ($in{'chroot'} eq "/") {
55 if ($rootdir eq "/") {
60 # Only use last filename by default
61 $in{'file'} =~ s/\s+$//;
62 if ($in{'file'} =~ /\n(.*)$/) {
66 if ($in{'file'} =~ /^(([a-z]:)?.*\/)([^\/]*)$/i && $in{'file'} !~ /\.\./) {
67 # File entered is valid
72 # Fall back to default
74 $dir .= '/' if ($dir !~ /\/$/);
77 $add = int($in{'add'});
79 if (!(-d $in{'chroot'}.$dir)) {
80 # Entered directory does not exist
84 if (!&allowed_dir($dir)) {
85 # Directory is outside allowed root
90 # Work out the top allowed dir
91 $topdir = $rootdir eq "/" || $rootdir eq "c:" ? $rootdir :
92 $access{'otherdirs'} ? "/" : $rootdir;
94 if ($in{'frame'} == 0) {
97 if ($in{'type'} == 0) {
98 print "<title>$text{'chooser_title1'}</title>\n";
100 elsif ($in{'type'} == 1) {
101 print "<title>$text{'chooser_title2'}</title>\n";
103 print "<frameset rows='*,50'>\n";
104 print "<frame marginwidth=5 marginheight=5 name=topframe ",
105 "src=\"chooser.cgi?frame=1&file=".&urlize($in{'file'}).
106 "&chroot=".&urlize($in{'chroot'}).
107 "&type=".&urlize($in{'type'})."&add=$add\">\n";
108 print "<frame marginwidth=0 marginheight=0 name=bottomframe ",
109 "src=\"chooser.cgi?frame=2&file=".&urlize($in{'file'}).
110 "&chroot=".&urlize($in{'chroot'}).
111 "&type=".&urlize($in{'type'})."&add=$add\" scrolling=no>\n";
112 print "</frameset>\n";
114 elsif ($in{'frame'} == 1) {
115 # List of files in this directory
119 function fileclick(f, d)
121 curr = top.frames[1].document.forms[0].elements[1].value;
123 // Double-click! Enter directory or select file
125 // Enter this directory
126 location = "chooser.cgi?frame=1&add=$add&chroot=$in{'chroot'}&type=$in{'type'}&file="+f+"/";
129 // Select this file and close the window
131 top.opener.ifield.value = f;
134 if (top.opener.ifield.value != "") {
135 top.opener.ifield.value += "\\n";
137 top.opener.ifield.value += f;
143 top.frames[1].document.forms[0].elements[1].value = f;
147 function parentdir(p)
149 top.frames[1].document.forms[0].elements[1].value = p;
150 location = "chooser.cgi?frame=1&chroot=$in{'chroot'}&type=$in{'type'}&file="+p;
155 print "<b>",&text('chooser_dir', &html_escape($dir)),"</b>\n";
156 opendir(DIR, $in{'chroot'}.$dir) ||
157 &popup_error(&text('chooser_eopen', "$!"));
158 print "<table width=100%>\n";
159 foreach $f (sort { $a cmp $b } readdir(DIR)) {
160 $path = "$in{'chroot'}$dir$f";
161 if ($f eq ".") { next; }
162 if ($f eq ".." && ($dir eq "/" || $dir eq $topdir.'/')) { next; }
163 if ($f =~ /^\./ && $f ne ".." && $access{'nodot'}) { next; }
164 if (!(-d $path) && $in{'type'} == 1) { next; }
168 $isdir = 0; undef($icon);
169 if (-d $path) { $icon = "dir.gif"; $isdir = 1; }
170 elsif ($path =~ /\.([^\.\/]+)$/) { $icon = $icon_map{$1}; }
171 if (!$icon) { $icon = "unknown.gif"; }
174 $dir =~ /^(.*\/)[^\/]+\/$/;
175 $link = "<a href=\"\" onClick='parentdir(\"".&html_escape(quotemeta($1))."\"); return false'>";
178 $link = "<a href=\"\" onClick='fileclick(\"".&html_escape(quotemeta("$dir$f"))."\", $isdir); return false'>";
180 print "<td>$link<img border=0 src=/images/$icon></a></td>\n";
181 print "<td nowrap>$link".&html_escape($f)."</a></td>\n";
182 printf "<td nowrap>%s</td>\n",
183 $st[7] > 1000000 ? int($st[7]/1000000)." MB" :
184 $st[7] > 1000 ? int($st[7]/1000)." kB" :
186 @tm = localtime($st[9]);
187 printf "<td nowrap><tt>%.2d/%s/%.4d</tt></td>\n",
188 $tm[3], $text{'smonth_'.($tm[4]+1)}, $tm[5]+1900;
189 printf "<td nowrap><tt>%.2d:%.2d</tt></td>\n", $tm[2], $tm[1];
196 elsif ($in{'frame'} == 2) {
197 # Current file and OK/cancel buttons
201 function filechosen()
204 top.opener.ifield.value = document.forms[0].path.value;
207 if (top.opener.ifield.value != "") {
208 top.opener.ifield.value += "\\n";
210 top.opener.ifield.value += document.forms[0].path.value;
217 print "<form onSubmit='filechosen(); return false'>\n";
218 print "<tr><td><input type=submit value=\"$text{'chooser_ok'}\"></td>\n";
219 print "<td><input name=path size=45 value=\"$dir$file\"></td></tr>\n";
226 # Returns 1 if some directory should be listable
230 return 1 if ($rootdir eq "" || $rootdir eq "/" || $rootdir eq "c:");
231 foreach my $allowed ($rootdir, split(/\t+/, $access{'otherdirs'})) {
232 return 1 if (&is_under_directory($allowed, $dir));