Question

This is a convoluted one so bear with me. I have a Perl script that is located on a Windows VirtualBox guest. I want to call this script from the Linux host and have it read a shared folder from the host. The reading of the folder fails.

On the host I call this script and it gives me the following output:

host:~/$ ./script.pl /nfs/nasi/temp
[2014-04-02 10:50:55] Uploading file records to localhost
[2014-04-02 10:50:55] Running VirtualBox for Kaspersky
fatal: opendir(E:\nasi\temp) failed: No such file or directory
[2014-04-02 10:50:56] Uploading malware samples data to localhost
host:$

The script converts the argument /nfs/nasi/temp to E:\nasi\temp and calls the script using the following command:

/usr/bin/VBoxManage guestcontrol <guest> execute \
  --image "C:\strawberry\perl\bin    \perl.exe"   \
  --username <user> --password <pass>              \
  --wait-stdout --wait-stderr --wait-exit --        \
  "C:\antivirus\kaspersky.pl" "E:\nasi\temp"

When I run this same script using the same option from the guest directly however I get the following:

C:\antivirus>C:\strawberry\perl\bin\perl.exe C:\antivirus\kaspersky.pl E:\nasi\temp
[2014-04-02 10:54:19] Running Kaspersky Antivirus
[2014-04-02 10:54:20] Parsing Kaspersky report
[2014-04-02 10:54:20] Uploading Kaspersky results to 10.0.0.1
C:\antivirus>

But wait, it gets weirder. When instead of providing the shared directory E:\ I instead point it to C:\ it has no problem reading the directory and just happily keeps going. So the error only shows up when I run the command from the host through VirtualBox and point it to the share.

Here is the relevant code:

sub createSamplesMap {
    opendir( my $dh, $ARGV[0] ) or
        die "fatal: opendir($ARGV[0]) failed: $!\n";
    my @files = readdir( $dh );
    foreach my $file ( @files ) {
        if (! -d $file ) {
            ...
        }
    }
    closedir($dh);
}

I tried different ways of reading the filenames from the directory but they didn't work. Here's what I tried.

my @files = <$ARGV[0]\\*>;
my @files = glob( $ARGV[0] . '\\*' );

I don't know whether to blame perl or virtualbox. Anyone have any ideas on what the problem might be?

  • Windows 7, Strawberry Perl v5.18.2
  • Ubuntu 12.04.04, Perl v5.14.2
  • VirtualBox 4.2.16r86992

crosspost: https://forums.virtualbox.org/viewtopic.php?f=2&t=61011

Was it helpful?

Solution

I've found the problem. As mentioned on the virtualbox forum there was a problem with the environment variables set when running the perl script. After much googling I also found a blog post from kissmyarch where he describes how he solved the problem.

You can set environment variables using the --environment option in VBoxManage guestcontrol and according to kissmyarch you need to set USERPROFILE to get it to work. This did not work for me.

So instead I used the following code from the script to figure out what environment variables were set:

foreach $key (sort keys(%ENV)) {
  print "$key = $ENV{$key}\n";
}

and ran that both on the guest and from guestcontrol to compare the environments. My command now looks like this:

/usr/bin/VBoxManage guestcontrol <vm> execute \
   --image "C:\strawberry\perl\bin\perl.exe" \
   --username <user> --password <pass> \
   --environment "USERPROFILE=C:\Users\<user>" \
   --environment "APPDATA=C:\Users\<user>\AppData\Roaming" \
   --environment "LOCALAPPDATA=C:\Users\<user>\AppData\Local" \
   --environment "HOMEDRIVE=C:" \
   --environment "HOMEPATH=\Users\<user>" \
   --environment "LOGONSERVER=\\\<server>" \
   --environment "SESSIONNAME=Console" \
   --environment "TEMP=C:\Users\<user>\AppData\Local\Temp" \
   --environment "TMP=C:\Users\<user>\AppData\Local\Temp" \
   --environment "USERDOMAIN=<domain>" \
   --environment "USERNAME=<user>" \
   --wait-stdout --wait-stderr --wait-exit \
   -- "C:\antivirus\kaspersky.pl" "E:\nasi\temp"

Somewhere in that big pile of environment variables is one that is important.

Thanks to all that helped.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top