Pompous logo
www . DanYEY . co . uk
Dirty Perl Hacks

Here are a selection of stinking perl hacks, which might be useful to some people.

Win32 Uptime

Since my installation of PHP doesn't have the Windows API functions (they seem to have been removed/deprecated at version 4.2.3), I was forced to resort to executing perl in order to have the system uptime display on a webpage. Obviously, this will only work with perl on Windows. Here's the code:

print Win32::GetTickCount();

Very simple isn't it? I collected the output in PHP and calculated days, hours, etc, there. The problem with its simplicity is that it will wrap to zero every 49 days or so. This is ok for me, because we have power cuts more often than that.

Win32 Disk Usage

This requires Windows and a perl module called Win32::API which can easily be downloaded with ppm which comes with ActiveState Perl.

use Win32::API;
$buserfree = " " x 8;
$btotal = " " x 8;
$btotalfree = " " x 8;
$df = new Win32::API('kernel32', 'GetDiskFreeSpaceEx', 'PPPP', 'N');
$ret = $df->Call('C:\\', $buserfree, $btotal, $btotalfree);
($userfree, $high) = unpack('II', $buserfree);
($total, $high) = unpack('II', $btotal);
($totalfree, $high) = unpack('II', $btotalfree);
if ($totalfree > 1024*1024)
{
  $free = int($totalfree / (1024 * 1024));
  print $free." MB";
}
elsif ($totalfree > 1024)
{
  $free = int($totalfree / 1024);
  print $free." KB";
}
else
{
  print $totalfree." bytes";
}

Win32 Memory Usage

Also requires Windows and Win32::API.

use Win32::API;
$bmem = " " x 32;
$mem = new Win32::API('kernel32', 'GlobalMemoryStatus', 'P', 'N');
$mem->Call($bmem);
($len,
$load,
$totalphys,
$availphys,
$totalpage,
$availpage,
$totalvirt,
$availvirt) = unpack('IIIIIIII', $bmem);

print $load."%\n";
print ''.int($totalphys/1024/1024)." MB\n";
print ''.int($availphys/1024/1024)." MB\n";
print ''.int($totalpage/1024/1024)." MB\n";
print ''.int($availpage/1024/1024)." MB\n";

Data Generation Over Time

This works out how much data is generated in a particular directory each month. It's not pretty, but it works.

use File::stat;

$path = "C:\\some\\directory\\";

opendir($dir, $path);
@times = ();
@sizes = ();
while ($file = readdir($dir))
{
  $s = stat($path.$file);
  $times[scalar(@times)] = $s->mtime;
  $sizes[scalar(@sizes)] = $s->size;
}
@now = localtime(time);
$past_year = $now[5];
foreach $timestamp (@times)
{
  @time = localtime($timestamp);
  if ($time[5] < $past_year)
  {
    $past_year = $time[5];
  }
}
for ($year = $past_year; $year <= $now[5]; $year++)
{
  for ($month = 0; $month < 12; $month++)
  {
    $totalbytes = 0;
    $files = 0;
    for ($i = 0; $i < scalar(@times); $i++)
    {
      @time = localtime($times[$i]);
      if ($time[5] == $year && $time[4] == $month)
      {
        $totalbytes += $sizes[$i];
        $files++;
      }
    }
    #Month/Year Files Bytes AvgSize
    print (($month+1)."/".($year+1900)."\t".$files."\t".$totalbytes.
           "\t".($files > 0 ? $totalbytes/$files : 0)."\n");
  }
}
closedir($dir);