0

Here is my situation:

use strict;
use Cwd;
use Getopt::Long;
Getopt::Long::Configure('pass_through');
use File::Spec;
use File::Basename;

1) -out=/some/place/some_filename.txt
2) -out=/some/place/
3) -out=some_filename.txt

Any user can give any '-out=' as exampled above. I am interested in the pathname because I have to check if the directory is writable to create/overwrite a log file, and exit with a warning if the directory is not writable.

If -out= is option 1, then fileparse will give me '/some/place' and I can -w on that.

If -out= is option 2, then I can just -d and -w, then attach a default filename. Something like '/some/place/default_filename.txt'

If -out= is option 3, I have to attach 'my $cwd' to the filename. Something like '/current/working/dir/some_filename.txt'

The requested file may or may not pre-exist. The filename may be .log or .txt or .dat or no extension at all, depending on the user's whim, and I have to create/overwrite that file as needed.

So my question for the more experienced Perl tacticians here, since -out= will be uncertain from user to user, what is the best method to extract the pathname? I can do 'if (-d $out)', but what if the user just gave a filename? I may get lucky and the user may give the full path/filename, or just the directory path. Or the user may be satisfied with having his data in current working directory and will give only a filename. I inserted a filename into fileparse and got: "$path=./"

Roderick

Rod
  • 61
  • 4

1 Answers1

1

You can simply check if your parameter is a directory (-d $out) and add default file name to it in that case. Then all you need to check if resultant file is writable and bail out if it isn't:

$out .= "/default_filename.txt" if -d $out;
die "File $out is not writable!" unless -w $out;
# everything ok, create file at $out:
open FILE, ">", $out or die "Cannot open $out for writing!";
# ...
mvp
  • 111,019
  • 13
  • 122
  • 148
  • What I have now does what I want, but I think it is somewhat clunky and clumsy. – Rod Dec 29 '13 at 07:01
  • Basically, if (-d $out) return a directory, then I can do a -w. But if (-d $out) is NOT a directory, then I have to assume that it may contain a '/complete/path/filename.txt' so I pass $out to fileparse to extract the path, if any. – Rod Dec 29 '13 at 07:10
  • Why do you need to extract path? At the end of the day, you just need a file to write into, right? And letting user to specify a directory is just a convenience, and this method solves that, without any need for parsing. – mvp Dec 29 '13 at 07:13
  • I need to verify if path is writable. Many locations are not owned by the requester(s) and are often wrongly assumed to be writable by everyone. Someone would extract data and deposit into someone else's directory and that person may not gave the rest of us permission to work in that directory. – Rod Dec 29 '13 at 07:23
  • It will be automatically checked when you will try to open such file for writing (`open FILE, ">", $out`). If you want your script to be the one to enforce permissions, you are doing it wrong - this is not the way to write secure programs. – mvp Dec 29 '13 at 07:27
  • So the better way is to eval an 'open FILE, ">", $out), and if cannot, I can safely assume the directory does not have write permission? I am not trying to set permission, am only trying to alert the user that his destination is not workable. – Rod Dec 29 '13 at 07:34
  • `-w $out` tells if file or directory is writable according to effective permissions you have, but it does not 100% guarantee that until you really try to open/create file using `open FILE, ">", $out`. For example, file on CD-ROM may have `rw-` permissions and `-w` would return true, but you would not be able to actually open such file for writing. – mvp Dec 29 '13 at 07:43
  • Am working in an environment where there are supposedly open directories, either temporary or permanent, where people will deposit/remove data as needed, and if someone did not open a directory where/when he is supposed to, he will hear about it. My script is supposed to verify the destination is writable BEFORE collecting/depositing data. So am just looking for a more elegant way than what I have: -d -w and fileparse. – Rod Dec 29 '13 at 07:55
  • In that case, simple `-w $out` would work, and you do not need to fileparse. – mvp Dec 29 '13 at 07:58
  • Will explore that further. Thnx much for your help. – Rod Dec 29 '13 at 08:04
  • @rod you don't need to eval the open. Just test the error code it returns - "open ...params... or dowhatyouneedtodoonerror" – justintime Dec 30 '13 at 05:43