1

Let me preface by saying I'm a total novice at perl.

I need to modify rules on a mail system. I can access the rules as an array and I believe the array contains subarrays. I need to modify one particular element and preserve the rest. My problem is I'm confused as to what the array type really is and how to consistently access the elements.

There may be more than one set of rules, but I'm only interested in processing rules with a priority of '1', which is $Rule[0]. Within $Rule[3] I need to parse the addresses.

use strict;
use Data::Dumper qw(Dumper);

my $Rules=$cli->GetAccountMailRules($account);

print Dumper \@$Rules;

    foreach my $Rule (@$Rules) {
      if($Rule->[0]=~/1/) {
        my $pri=$Rule->[0];
        my $type=$Rule->[1];
        my $auto=$Rule->[2];
        my $actions=$Rule->[3];
        my $action1;
        my $auto1;
        my $auto2;
        my @newRule;
        my $oldDest;
        print "\n";

        print "Priority:\n";
        print Dumper \$pri;
        print "\n";

        print "Rule Type:\n";
        print Dumper \$type;
        print "\n";

        print "Forward Auto?:\n";
        print Dumper \$auto;
        print "\n";

        print "Actions:\n";
        print Dumper \$actions;
        print "\n";

        foreach my $ax (@$actions) {
          $action1=$ax->[0];
          $oldDest=$ax->[1];
        } 

        my @addresses=split /[;,]|\\e/, $oldDest;
        my @dests = grep(/corp.com|corp1.com|corp2.com|corp3.com/, @addresses);
        my $newDest = join(",", @dests);
        if (@$auto) {
          foreach my $au (@$auto) {
            $auto1=$au->[0];
            $auto2=$au->[1];    
          }
          @newRule=(
            [ $pri, $type,
            [[$auto1,$auto2]],
            [[$action1,$newDest]]
            ]
            );
        } else {
          @newRule=(
            [ $pri, $type,
            [],
            [[$action1,$newDest]]
            ]
            );
        }
      }  
    }
}

Output thusly:

# perl removeRules.pl
$VAR1 = [
          [
            '1',
            '#Redirect',
            [
              [
                'Human Generated',
                '---'
              ]
            ],
            [
              [
                'Mirror to',
                '[email protected]\\[email protected]\\[email protected]'
              ]
            ]
          ]
        ];

Priority:
$VAR1 = \'1';

Rule Type:
$VAR1 = \'#Redirect';

Forward Auto?:
$VAR1 = \[
            [
              'Human Generated',
              '---'
            ]
          ];

Actions:
$VAR1 = \[
            [
              'Mirror to',
              '[email protected]\\[email protected]\\[email protected]'
            ]
          ];

The problem I'm running into is there is an option within $actions to discard emails after forwarding, which introduces new elements (or subarray?) into $actions:

# perl removeRules.pl
$VAR1 = [
          [
            '1',
            '#Redirect',
            [
              [
                'Human Generated',
                '---'
              ]
            ],
            [
              [
                'Mirror to',
                '[email protected]\\[email protected]\\[email protected]'
              ],
              [              <---- Begin new elements
                'Discard',   
                '---'
              ]              <---- End new elements
            ]
          ]
        ];

Priority:
$VAR1 = \'1';

Rule Type:
$VAR1 = \'#Redirect';

Forward Auto?:
$VAR1 = \[
            [
              'Human Generated',
              '---'
            ]
          ];

Actions:
$VAR1 = \[
            [
              'Mirror to',
              '[email protected]\\[email protected]\\[email protected]'
            ],
            [
              'Discard',
              '---'
            ]
          ];

I tried testing to see if they can be referenced as additional elements in $actions but it throws off the index.

my $action2;
my $action3;

print "Actions:\n";
print Dumper \$actions;
print "\n";

foreach my $ax (@$actions) {
  $action1=$ax->[0];
  $oldDest=$ax->[1];
  $action2=$ax->[2];
  $action3=$ax->[3];
} 

print "  action1 $action1\n";
print "  oldDest $oldDest\n";
print "  action2 $action2\n";
print "  action3 $action3\n";

Output:

Actions:
$VAR1 = \[
            [
              'Mirror to',
              '[email protected]\\[email protected]\\[email protected]'
            ],
            [
              'Discard',
              '---'
            ]
          ];

  action1 Discard
  oldDest ---
Use of uninitialized value $action2 in concatenation (.) or string at removeRules.pl line 107, <GEN0> line 4.
  action2
Use of uninitialized value $action3 in concatenation (.) or string at removeRules.pl line 108, <GEN0> line 4.
  action3

Thank you in advance.

1 Answer 1

3

Using this:

        [
          [
            'Mirror to',
            '[email protected]\\[email protected]\\[email protected]'
          ],
          [
            'Discard',   
            '---'
          ]
        ]

This is a reference to an array (the outer [..]) that has two items. Each item is again a reference to an array.

First item (position 0 of outer array reference) is

          [
            'Mirror to',
            '[email protected]\\[email protected]\\[email protected]'
          ],

and second (position 1) is:

          [
            'Discard',   
            '---'
          ]

If $ractions is this outer array, then the above two items are respectively under $ractions->[0] and $ractions->[1].

Since they are both an array reference again you can access their items using the same construct, or using a Perl property, you can remove the second array.

In short:

  • 'Mirror to' can be accessed by $ractions->[0]->[0] or shorter $ractions->[0][0]
  • '[email protected]\[email protected]\[email protected]' can be accessed by $ractions->[0]->[1]
  • 'Discard' can be accessed by $ractions->[1]->[0]
  • '---' can be accessed by $ractions->[1]->[1]

Be aware however that $VAR1 = \[ shows that you have a reference over a reference. So you will need an extra step of derefencing:

  DB<1> use Data::Dumper;

  DB<2> @a=(1,2)

  DB<3> print Data::Dumper::Dumper(@a);
$VAR1 = 1;
$VAR2 = 2;

  DB<4> print Data::Dumper::Dumper(\@a);
$VAR1 = [
          1,
          2
        ];

  DB<5> print Data::Dumper::Dumper(\\@a);
$VAR1 = \[
            1,
            2
          ];

PS: do not use corp.com or anything like that when you need to obfuscate domain names. See guidance in RFC2606 or TL;DR: use example.com

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.