more File::Spec woes

barbie on 2002-10-22T14:44:10

I have an HTML form, which includes a file field that is passed to my CGI script. In order to store it in the system I just need the filename from the variable given. Liking the idea of using existing modules to do the work, I thought I'd use splitpath() from File::Spec's repetoire.

Unfortunately it breaks :(

The reason is due to the fact that File::Spec cannot cope with different file specifications when used in a cross platform way. In the scenario above the user is using a browser on a Win32 box, but the code is running on a Unix box, thus the File::Spec::Unix.pm is loaded.

The following code:

my $source = "c:\mydirs\myfile.doc"; # the value from the HTML file form field
my ($volume,$directories,$filename) = splitpath($source);
print "volume=[$volume]\ndirectories=[$directories]\nfilename=[$filename]\n";

results in:

volume=[]
directories=[]
filename=[c:\mydirs\myfile.doc]

So that when I try to save "/var/www/mysite/html/downloads/c:\mydirs\myfile.doc" if fails miserably.

I now use a simple regex to extract everything from the last directory delimiter (if there is one) to the end of the string. I guess it was a bit pointless calling another function to do it, but at least it highlighted the problem.


File::Spec

lachoy on 2002-10-23T02:42:16

Can't you specify a platform-specific version? For instance, the following works ok on my linux workstation:
my @elements = File::Spec::Win32->splitpath( $foo );

Re:File::Spec

barbie on 2002-10-24T16:52:02

No because that'll break when a Linux user posts a file from their browser of choice.

The problem is that File::Spec ridigly describes the path format for one system. If you specify an Win32 system, no other system will work.

Thanks to muttley I now use the following:

use File::Basename;
fileparse_set_fstype("MSWin32"); # just in case it's in Windows style
my $realname = basename($source);

And that seems to work a treat.

Re:File::Spec

lachoy on 2002-10-25T01:19:27

Right, but you can generally get this information from whatever the browser passes as the UserAgent. But that's likely a little too much work just to get a filename without associated directory :-)

I was just responding to the perceived "I need to parse a filename from another type of filesystem" need.

Re:File::Spec

barbie on 2002-10-25T10:11:01

...get this information from whatever the browser passes as the UserAgent.
Thats a big assumption of the fact that the client platform information (a) is there and (b) is accurate.

Admittedly for the majority of our purposes it will be there, but there are those few cases when it could pose a problem. At least with the way muttley suggested we now cover a bigger majority of platforms that will be accessing our systems. If we could cover Macs too, then I think we'd have the lot.

Re:File::Spec

jdavidb on 2002-10-25T17:23:24

Does CGI.pm handle file uploading in a cross-platform way? I'm suggesting, but I've never tried it myself.