Hello,

I am trying to write something to edit a sendmail aliases file via the web. The script should have a drop down menu with the different pager numbers in it. When someone picks their number out of the list, the script should replace one entry in the aliases file. I have written everything with the exception of replacing the entry in the aliases file. This is what i have so far:

#!/usr/bin/perl -wT 
use CGI qw(:standard);
use CGI::Carp qw(warningsToBrowser fatalsToBrowser);
#use strict;
use warnings;

my $q = new CGI;
print $q->header( "text/html" );
my $counter;


open(ALIAS, "/etc/aliases") or die "Unable to open tmp file:$!\n";

while(<ALIAS>)
{
        if(/pageoncall/)
        {   
                $currentOncall = $_;    
        }   


}

$buffer = $ENV{'QUERY_STRING'};
print $buffer;
print <<EOF;

        <html>
        <head>
        <title>Answer the call!</title>
        </head>
        <body>
                <p>$oncall</p>
                <p>If you want to answer the call, please enter your phone number below. (Only the number should be entered, no domain.)</p>
                <form action="URL/aliases.cgi" method="GET">
                Please select a number: <select name="pager">
                                        <option>
                                        <option>1234567890\@messaging.sprintpcs.com
                                        <option>1234567890\@archwireless.net
                                        <option>0987654321
                                        </select><input type = "submit">
        </form>
        </body>
        </html>
EOF

I am also wondering how to convert the 1234567890%40archwireless.net created by the script to the @domain format.

I don't understand what you are trying to do. Can you explain it better? What does the aliases file look like?

I don't understand what you are trying to do. Can you explain it better? What does the aliases file look like?

I am sorry, i should have explained what i am trying to do. Where i work we have one person who is on call every week. The on call employee is rotated once per week. One part of our setup sends emails out too all the engineers when there's a failure. Since this email isn't currently being sent to pagers, i have setup an alias so the mail is pushed out to the pagers. That looks something like this:

## Alias file ##
pageoncall: 1234567890@pager.com

So when an email is sent to pageoncall@doamin.com, it is actually sent to the 123456780@pager.com address.

So, what i am trying to do is write a small page where they can go and change the pager number that is oncall. I have gotten the whole page done for the most part but am stuck on how to change just that one line within the text file.

assume you have the pager number already in a scalar, untested code:

my $newpagernum = '1234567890';
my $file = '/etc/aliases';
change_pager($newpagernum,$file);

sub change_pager {
   local @ARGV = @_;
   if (@ARGV != 2) { 
      die "Usage: Incorrect number of arguments [pagernumber, file]: $0\n"; 
   }
   my $num = shift @ARVG;
   local $^I = '.bak'; #inplace edit mode and creates a backup of the file
   while(<>) {
      if(/^pageoncall: \d+(\Q@pager.com\E)/) {
         print "pageoncall: $num$1\n";
      }
      else {
         print;
      }
}

Try the above on a dummy aliases file and see how it works, then work it into your existing program if all is well.

assume you have the pager number already in a scalar, untested code:

local $^I = '.bak'; #inplace edit mode and creates a backup of the file
   while(<>) {
      if(/^pageoncall: \d+(\Q@pager.com\E)/) {
         print "pageoncall: $num$1\n";
      }
      else {
         print;
      }
}

Could you please give me a little explanation on the above code? I am not sure what some of it does.

I am guessing the $^I is pretty much the same as the -i switch when editing a file on the command line with the substitute command.

I know what while(<>) does.

The area that i am really getting fuzzy with is with the if statement. I know the first part looks for a line starting with pageroncall:, but the rest is greek to me. Could you please explain this to me?

Could you please give me a little explanation on the above code? I am not sure what some of it does.

I am guessing the $^I is pretty much the same as the -i switch when editing a file on the command line with the substitute command.

I know what while(<>) does.

The area that i am really getting fuzzy with is with the if statement. I know the first part looks for a line starting with pageroncall:, but the rest is greek to me. Could you please explain this to me?

Correct, $^I is the same as -i.

if(/^pageoncall: \d+(\Q@pager.com\E)/) {

the "if" condition is a regexp that finds the line that starts wih "pageoncall:" followed by a space and one or more digits: \d+. This part (\Q@pager.com\E) captures the email address
and stores it in $1.

\Q tells perl to escape meta characters like @ and . in the string so they are treated as literal characters, the \E tells perl to where to stop escaping meta characters.

The next line replaces the new number with the old and reprints the line back into the file.

print "pageoncall: $num$1\n";

the other 'print' line just prints the rest of the lines back into the file.

Did it work?

The "if" condition probably should be written like this:

if(/^pageoncall:) {
         print "pageoncall: $num\@pager.com\n";
      }

I am about to try this, i just want to be sure i understand what's happening. I want to learn this stuff. :)

How is it printing back to the file? I don't see where you designate where to print to? Isn't the default print location/device stdout/display/screen, etc?

-- EDIT --

I tried this without success.

Here's the code:

#!/usr/bin/perl


use CGI qw(:standard);
#open(FILE, "/etc/aliases") or die "Couldn't open $0";
my $file = '/etc/aliases';    
    
        print header('text/html'),
                start_html('Answer the call!'),
                h1('Select your pager number and click submit:'),
                start_form,
                popup_menu(-name=>'pager',
                           -values=>['',1234567890@messaging.sprintpcs.com',
                                     '1234567890@archwireless.net',
                                     '0987654321@archwireless.net']),p,
                submit,
                end_form;

        if (param() )
        {   
                my $pager       = param('pager');

                if($pager == '') 
                {   
                        print "You selected an invalid number, please try again.";
                }   

                change_num($pager,$file);
        }   
    

sub change_num 
{
        local @ARGV = @_; 
        if(@ARGV != 2)
        {   
                die "Usage: Incorrect number of arguments.";
        }   

        my $number = shift @ARGV;

        local $^I = '.bak';

        while(<>)
        {   
                if(/^pageoncall:/)
                {   
                        print "pageoncall: $number\n";
                }   
        }   
}

this is a bit of perl magic:

@ARGV = (list of files);
while (<>){

Quoted from perlvar:

# ARGV

The special filehandle that iterates over command-line filenames in @ARGV . Usually written as the null filehandle in the angle operator <> . Note that currently ARGV only has its magical effect within the <> operator; elsewhere it is just a plain filehandle corresponding to the last file opened by <> . In particular, passing \*ARGV as a parameter to a function that expects a filehandle may not cause your function to automatically read the contents of all the files in @ARGV .
# $ARGV

contains the name of the current file when reading from <>.
# @ARGV

The array @ARGV contains the command-line arguments intended for the script. $#ARGV is generally the number of arguments minus one, because $ARGV[0] is the first argument, not the program's command name itself. See $0 for the command name.
# ARGVOUT

The special filehandle that points to the currently open output file when doing edit-in-place processing with -i. Useful when you have to do a lot of inserting and don't want to keep modifying $_. See perlrun for the -i switch.

/end quote/

http://perldoc.perl.org/perlvar.html

I hope I did not offend you by quoting the manual, but it explains it very well.

No. You didn't offend me at all. That edit came from a question i asked first thing this morning. It was a stupid question that i should have looked up first. I asked why when i compared strings via the == operator it wouldn't work. A quick google turned up the right answer. :)

This article has been dead for over six months. Start a new discussion instead.