[exim] Exim Webmin Module.

Top Page

Reply to this message
Author: Grant Peel
Date:  
To: exim-users
Subject: [exim] Exim Webmin Module.
Hi all,

The perl code below has is a file from a Webmin module used to interface with Exim, show stats manage queue etc. The issue is that the date does not decode properly. The code is quite old, and I have been hacking at it for weeks trying to get it to work correctly. I have attempted to contact the original developer, but suspect his email is not been checked.

I am posting to this list thinking perhaps some of you may have some expierence with the base62 encoding, and hopefully perl!

If anyone would like to take a shot at it ....

Example
1RkkUB-000CAI-Ce        is being decoded a s:         Sat Apr 23 16:10:52 2005
which is not correct.


Here is the code: (Message.pm)

I suspect the issue is with the base62_to_decimal sub near the end.




#!/usr/bin/perl

package Exim::Message;

require 5;

use strict;
use integer;

sub uli # 'uli' stands for Unique Local Identifier
  {
    my $self = shift;
    if (@_) {
      my $uli = shift;


      return undef if $uli !~ /[0-9a-zA-Z]{6}-[0-9a-zA-Z]{6}-[0-9a-zA-Z]{2}/;
      $self->{uli} = $uli
    }
    return $$self{uli}
  }


sub time
  {
    my $self = shift;
    if (@_) {
      my $time = shift;
      my $units = 'smhdw';


      $time =~ /^(\d+)([$units])/ or return undef;


      $$self{rtime} = { value => $1, unit => $2 };


      my ($value, $unit) = ($1, index($units, $2));
      my @coef = (1, 60, 60, 24, 7);


      while ($unit > 0) { $value *= $coef[$unit--] }
      $$self{time} = $value;
    }
    return $$self{time}
  }


sub rounded_time
  {
    my $self = shift;
    return $$self{rtime}
  }


sub size
  {
    my $self = shift;
    if (@_) {
      my $size = shift;
      $size = defined $size?$size:0;


      my $units = '_KMG';


      my $bytes;


      if ($size =~ /\./) {
        $size =~ /^(\d+\.?\d+)([$units])?/ or return undef;
        $$self{rsize} = { value => $1, unit => $2.'B' };
        $bytes = $1*1024**index($units, $2);
      }
      else {
        $size =~ /^(\d+)([$units]?)/ or return undef;
        $$self{rsize} = { value => $1, unit => $2.'B' };
        $bytes = $1 << 10*index($units, $2);
      }


      $$self{size} = $bytes;
    }


    return $$self{size}
  }


sub rounded_size
  {
    my $self =shift;
    return $$self{rsize}
  }


sub sender
  {
    my $self = shift;
    if (@_) {
      my $sender = shift;


      $sender =~ s/^\<(.*)\>$/$1/;
      $$self{sender} = $sender;
    }
    return $$self{sender}
  }


sub status
  {
    my $self = shift;
    if (@_) { $$self{status} = shift()?1:0 }
    return $$self{status}
  }


sub undelivered
  {
    my $self = shift;
    if (@_) { push @{$$self{undelivered}}, @_ }
    return @{$$self{undelivered}};
  }


sub delivered
  {
    my $self = shift;
    if (@_) { push @{$$self{delivered}}, @_ }
    return @{$$self{delivered}};
  }


sub _init_
  {
    my $self = shift;


    my @fields = split ' ', shift;
    return undef if @fields < 4;


    &time ($self, shift @fields) or return undef;
    &size ($self, shift @fields) or return undef;
    &uli ($self, shift @fields) or return undef;
    &sender ($self, shift @fields);
    &status ($self, shift @fields);


    $$self{delivered} = [];
    $$self{undelivered} = [];


    local $_;
    foreach (@_) {
      chomp;
      next if /^$/;
      s/^\s+//;
      s/^D\s+//?&delivered($self, $_):&undelivered($self, $_)
    }
    return $self
  }


sub new
  {
    my $class = shift;
    $class = ref($class) || $class;


    my $self = bless {}, $class;


    if (@_) {
      $self->_init_ (split /\n/, shift ()) or return undef;
    }
    return $self;
  }


sub gmt
  {
    my $self = shift;


    return $$self{gmt} if defined $$self{gmt};


    return $$self{gmt} = gmtime base62_to_decimal ($$self{uli})
  }


sub is_frozen
  {
    my $self = shift;
    return $$self{status};
  }


# Converts base 62 ([0-9a-zA-Z]*) ASCII strings to decimal numbers.
# Example: &base62_to_decimal('15gY5D');
sub  base62_to_decimal
  {
    my @tab62 =
      (0,1,2,3,4,5,6,7,8,9,0,0,0,0,0,0,      # 0-9
       0,10,11,12,13,14,15,16,17,18,19,20,   # A-K
       21,22,23,24,25,26,27,28,29,30,31,32,  # L-W
       33,34,35, 0, 0, 0, 0, 0,              # X-Z
       0,36,37,38,39,40,41,42,43,44,45,46,   # a-k
       47,48,49,50,51,52,53,54,55,56,57,58,  # l-w
       59,60,61);                            # x-z


    my($d) = 0;
    my($O) = ord('0');
    my(@c) = unpack('C*', shift);
    while($#c >= 0) { $d = $d * 62 + $tab62[shift(@c) - $O] }
    return $d;
  }


-Thanks

-G