This file is indexed.

/usr/share/perl5/Term/Clui/FileSelect.pm is in libterm-clui-perl 1.68-1.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
# Term/Clui/FileSelect.pm
#########################################################################
#        This Perl module is Copyright (c) 2002, Peter J Billam         #
#               c/o P J B Computing, www.pjb.com.au                     #
#                                                                       #
#     This module is free software; you can redistribute it and/or      #
#            modify it under the same terms as Perl itself.             #
#########################################################################

package Term::Clui::FileSelect;
$VERSION = '1.68';
import Term::Clui(':DEFAULT','back_up');
require Exporter;
@ISA = qw(Exporter);
@EXPORT = qw(select_file);
@EXPORT_OK = qw();

no strict; no warnings;

my $home = $ENV{HOME} || $ENV{LOGDIR} || (getpwuid($>))[$[+7];
$home =~ s#([^/])$#$1/#;

sub select_file {   my %option = @_;
	if (!defined $option{'-Path'}) { $option{'-Path'}=$option{'-initialdir'}; }
	if (!defined $option{'-FPat'}) { $option{'-FPat'}=$option{'-filter'}; }
	if (!defined $option{'-ShowAll'}) {
		$option{'-ShowAll'} = $option{'-dotfiles'};
	}
	if ($option{'-Directory'}) { $option{'-Chdir'}=1; $option{'-SelDir'}=1; }
	my $multichoice = 0;
	if (wantarray && !$option{'-Chdir'} && !$option{'-Create'}) {
		$option{'-DisableShowAll'} = 1;
		$multichoice = 1;
	} elsif (!defined $option{'-Chdir'}) {
		$option{'-Chdir'} = 1;
	}

	if ($option{'-Path'} && -d $option{'-Path'}) {
		$dir=$option{'-Path'};
		if ($dir =~ m#[^/]$#) { $dir .= '/'; }
	} else {
		$dir = $home;
	}
	if ($option{'-TopDir'}) {
		if (!-d $option{'-TopDir'}) { delete $option{'-TopDir'};
		} elsif ($option{'-TopDir'} =~ m#[^/]$#) { $option{'-TopDir'} .= '/';
		}
		if (index $dir, $option{'-TopDir'}) { $dir = $option{'-TopDir'}; }
	}

	my ($new, $file, @allfiles, @files, @dirs, @pre, @post, %seen, $isnew);
	my @dotfiles;

	while () {
		if (! opendir (D, $dir)) { warn "can't opendir $dir: $!\n"; return 0; }
		if ($option{'-SelDir'}) { @pre = ('./'); } else { @pre = (); }
		@post = ();
		@allfiles = sort grep(!/^\.\.?$/, readdir D); closedir D;
		@dotfiles = grep(/^\./, @allfiles);
		if ($option{'-ShowAll'}) {
			if (@dotfiles && !$option{'-DisableShowAll'}) {
				@post='Hide DotFiles';
			}
		} else {
			@allfiles = grep(!/^\./, @allfiles);
			if (@dotfiles && !$option{'-DisableShowAll'}) {
				@post='Show DotFiles';
			}
		}
		# split @allfiles into @files and @dirs for option processing ...
		@dirs  = grep(-d "$dir/$_" && -r "$dir/$_", @allfiles);
		if ($option{'-Directory'}) {
			@files = ();
		} elsif ($option{'-FPat'}) {
			@files = grep(!-d $_, glob("$dir/$option{'-FPat'}"));
			my $length = $[ + 1 + length $dir;
			foreach (@files) { $_ = substr $_, $length; }
		} else {
			@files = grep(!-d "$dir/$_", @allfiles);
		}
		if ($option{'-Chdir'}) {
			foreach (@dirs) { s#$#/#; }
			if ($option{'-TopDir'}) {
				my $up = $dir; $up =~ s#[^/]+/?$##;   # find parent directory
				if (-1 < index $up, $option{'-TopDir'}) { unshift @pre, '../'; }
				# must check for symlinks to outside the TopDir ...
			} else { unshift @pre, '../';
			}
		} elsif (!$option{'-SelDir'}) {
			@dirs = ();
		}
		if ($option{'-Create'})     { unshift @post, 'Create New File'; }
		if ($option{'-TextFile'})   { @files = grep(-T "$dir/$_", @files); }
		if ($option{'-Owned'})      { @files = grep(-o "$dir/$_", @files); }
		if ($option{'-Executable'}) { @files = grep(-x "$dir/$_", @files); }
		if ($option{'-Writeable'})  { @files = grep(-w "$dir/$_", @files); }
		if ($option{'-Readable'})   { @files = grep(-r "$dir/$_", @files); }
		@allfiles = (@pre, (sort @dirs,@files), @post); # reconstitute @allfiles

		my $title;
		if ($option{'-Title'}) { $title = "$option{'-Title'} in $dir"
		} else { $title = "in directory $dir ?";
		}
		if ($option{'-File'}) { &set_default($title, $option{'-File'}) }
		$Term::Clui::SpeakMode{'dot'} = 1;
		if ($multichoice) {
			my @new = &choose ($title, @allfiles);
			$Term::Clui::SpeakMode{'dot'} = 0;
			return () unless @new;
			foreach (@new) { $_="$dir$_"; }
			return @new;
		}
		$new = &choose ($title, @allfiles);
		$Term::Clui::SpeakMode{'dot'} = 0;

		if ($option{'-ShowAll'} && $new eq 'Hide DotFiles') {
			delete $option{'-ShowAll'}; redo;
		} elsif (!$option{'-ShowAll'} && $new eq 'Show DotFiles') {
			$option{'-ShowAll'} = 1; redo;
		}
		if ($new eq "Create New File") {
			$new = &ask ("new file name ?");  # validating this is a chore ...
			if (! $new) { next; }
			if ($new =~ m#^/#) { $file = $new; } else { $file = "$dir$new"; }
			$file =~ s#/+#/#g;  # simplify //// down to /
			while ($file =~ m#./\.\./#) { $file =~ s#[^/]*/\.\./##; }  # zap /../
			$file =~ s#/[^/]*/\.\.$##;  # and /.. at end
			if ($option{'-TopDir'}) {  # check against escape from TopDir
				if (index $file, $option{'-TopDir'}) {
					$dir = $option{'-TopDir'}; next;
				}
			}
			if (-d $file) {  # pre-existing directory ?
				if ($option{'-SelDir'}) { return $file;
				} else {
					$dir=$file; if ($dir =~ m#[^/]$#) { $dir.='/'; } next;
				}
			}
			$file =~ m#^(.*/)([^/]+)$#;
			if (-e $file) { $dir = $1; $option{'-File'} = $2; next; } # exists ?
			# must check for creatability (e.g. dir exists and is writeable)
			if (-d $1 && -w $1) { return $file; }
			if (!-d $1) { &sorry ("directory $1 does not exist."); next; }
			&sorry ("directory $1 is not writeable."); next;
		}
		return undef unless $new;
		if ($new eq './' && $option{'-SelDir'}) { return $dir; }
		if ($new =~ m#^/#) { $file = $new; # abs filename
		} else { $file = "$dir$new";       # rel filename (slash always at end)
		}
		if ($new eq '../') { $dir =~ s#[^/]+/?$##; &back_up(); next;
		} elsif ($new eq './') {
			if ($option{'-SelDir'}) { return $dir; } $file = $dir;
		} elsif ($file =~ m#/$#) { $dir = $file; &back_up(); next;
		} elsif (-f $file) { return $file;
		}
	}
}
1;

__END__

=pod

=head1 NAME

Term::Clui::FileSelect - Perl module to ask the user to select a file.

=head1 SYNOPSIS

 use Term::Clui;
 use Term::Clui::FileSelect;
 $file = &select_file(-Readable=>1, -TopDir=>"/home", -FPat=>"*.html");
 @files = &select_file(-Chdir=>0, -Path=>$ENV{PWD}, -FPat=>"*.mp3");
 chdir &select_file(-Directory=>1, -Path=>$ENV{PWD});

=head1 DESCRIPTION

This module asks the user to select a file from the filesystem.
It uses the Command-line user-interface Term::Clui to dialogue with the user.
It offers I<Rescan> and I<ShowAll> buttons.
To ease the re-learning burden for the programmer,
the options are modelled on those of Tk::FileDialog
and of Tk::SimpleFileSelect,
but various new options are introduced, namely I<-TopDir>, I<-TextFile>,
I<-Readable>, I<-Writeable>, I<-Executable>, I<-Owned> and I<-Directory>

Multiple choice is possible in a limited circumstance;
when I<file_select> is invoked in a list context, with -Chdir=>0
and without -Create.  It is currently not possible
to select multiple files lying in different directories.

=head1 SUBROUTINES

=over 3

=item I<select_file>( %options );

=back

=head1 OPTIONS

=over 3

=item I<-Chdir>

Enable the user to change directories. The default is 1.
If it is set to 0, and I<select_file> is invoked in a list context,
and I<-Create> is not set, then the user can select multiple files.

=item I<-Create>

Enable the user to specify a file that does not exist. The default is 0.

=item I<-ShowAll> or I<-dotfiles>

Determines whether hidden files (.*) are displayed.  The default is 0.

=item I<-DisableShowAll>

Disables the ability of the user to change the
status of the ShowAll flag. The default is 0
(i.e. the user is by default allowed to change the status).

=item I<-SelDir>

If True, enables selection of a directory rather than a file.
The default is 0.
To I<enforce> selection of a directory, use the I<-Directory> option.

=item I<-FPat> or I<-filter>

Sets the default file selection pattern, in glob format, e.g. I<*.html>.
Only files matching this pattern will be displayed.
If you want multiple patterns, you can use formats like
I<*.[ch]> or
I<{*.cgi,*.pl}> - see I<File::Glob> for more details.
The default is "*".

=item I<-File>

The file selected, or the default file.
The default default is whatever the user selected last time in this directory.

=item I<-Path> or I<-initialdir>

The path of the selected file, or the initial path.
The default is $ENV{HOME}.

=item I<-Title>

The Title of the dialog box.
If I<-Title> is specified,
then Clui::FileSelect dynamically appends "in I</where/ever>" to it.
If I<-Title> is not specified,
Clui::FileSelect displays "in directory I</where/ever>".

=item I<-TopDir>

Restricts the user to remain within a directory or its subdirectories.
The default is "/".
This option, and the following, are not offered by Tk::FileDialog.

=item I<-TextFile>

Only text files will be displayed. The default is 0.

=item I<-Readable>

Only readable files will be displayed. The default is 0.

=item I<-Writeable>

Only writeable files will be displayed. The default is 0.

=item I<-Executable>

Only executable files will be displayed.
The default is 0.

=item I<-Owned>

Only files owned by the current user will be displayed.
This is useful if the user is being asked to choose a file for a I<chmod>
or I<chgrp> operation, for example.
The default is 0.

=item I<-Directory>

Only directories will be displayed.
The default is 0.

=back

=head1 BUGS

Three problem filenames will, if present in your file-system, cause confusion.
They are I<Create New File>, I<Show DotFiles> and I<Hide DotFiles>

=head1 AUTHOR

Peter J Billam www.pjb.com.au/comp/contact.html

=head1 CREDITS

Based on an old Perl4 library, I<filemgr.pl>,
with the options modelled after I<Tk::FileDialog> and I<Tk::SimpleFileSelect>.

=head1 SEE ALSO

http://www.pjb.com.au/ ,
http://search.cpan.org/~pjb ,
File::Glob ,
Term::Clui ,
Tk::FileDialog ,
Tk::SimpleFileSelect ,
perl(1) .

=cut