How can I get the extension entered by user in a Perl AGI script? - perl

I'm new to Asterisk AGI programming. Im trying to create a simple IVR, using asterisk-perl, where a user can enter any extension from 1 to 4. Here is my code so far:
use Asterisk::AGI;
$AGI = new Asterisk::AGI;
for($i = 0 ; $i < 2 ; $i++)
{
$AGI->exec('Playback','welcome');
$AGI->exec('WaitExten','5|m');
}
Now, I want to know the extension the user entered and take some action accordingly. How to get the extension entered by the user?
Thank You.

I believe you want to use get_data, allowing you to play a file and then wait a given time for a given number of digits e.g.:
$AGI->get_data('demo-welcome', 15000, 5);
See here

Well since the WaitExten command changes the user to a new extension, I suppose you can read the special variable ${EXTEN} after calling WaitExten. I'm not familiar with Asterisk::Perl though, I've only used FastAGI from Java, so I don't know the exact command, but there must be some command to read a variable's value.

Related

For loop to open files in Python

I am relatively new to Python and need to run a python macro through Abaqus. I am opening files e.g "nonsym1, nonsym2, nonsym3". I'm trying to do this with a loop. The code opens nonsym1 (in abaqus) and performs some operations on it, then is supposed loop back and do the same to the other files. Here is the code I'm trying...
for i in range (1,10):
filename = 'nonsym(i)'
step = mdb.openStep(
'C:/Users/12345678/Documents/Inventor/Aortic Dissection/%s.stp' %filename,
scaleFromFile=OFF)
My main issue is coming from the fact that the %s in the directory I think?...
error message when trying to run this macro Don't know how to best approach this, so any help would be great thanks! Still learning!
Instead of using filename=nonsym1-2-3-..., name the step files as integers 1.stp,2.stp,3.stp and then convert integers to the string values with %str(i)...
And use the code below:
for i in range (1,10):
step = mdb.openStep(
'C:/Users/12345678/Documents/Inventor/Aortic Dissection/%s.stp' %str(i), scaleFromFile=OFF)
To obtain equal quantity of odb files, modify the Job code line as similiar as this code.

How to save variable after closing mIRC?

I'm new to do this language and i'm trying to code my own bot. I alredy got the basics and manage to use variables and aliases, however i was looking forward to do a mini-game in my chat in which you could have your own pet, name it and level it up.
I could do all this, however my problem resides in that at the end of the day, i would close the program and all the pets would go away, and that kind of destroys the purpose of it.
I was wondering if there was any way in i could save these variables and reload them each time i open the program, maybe save them on a .txt?
Any suggestion are greatly appreciated.
I agree with one of the comments that it's best to go with .ini files for this problem.
An example of the syntax, taken from the url linked above:
writeini reminder.ini birthday jenna 2/28/1983
writeini reminder.ini birthday Mike 10/10/1990
This produces the following file:
[birthday]
jenna = 2/28/1983
Mike = 10/10/1990
And is to be read like this:
echo -a Mike: $readini(reminder.ini, n, birthday, mike)
echo -a Jenna: $readini(reminder.ini, n, birthday, jenna)
If you want more flexibility to define your own data format, you can also revert to plain text files. The basic /write and $read functions have some pretty neat functionality: see the docs
Something like this should work for writing:
; search if the pet is already saved
$read(pets.txt,ns,%petname)
if ($readn == 0) {
; append to end of file
write pets.txt %petname %age %mood
}
else {
; replace line
write -l $readn pets.txt %petname %age %mood
}
To retrieve specific pets:
var %pet_info = $read(pets.txt, ns, %petname)
; Split the found line on space (ASCII-code 32)
tokenize 32 %pet_info
var %age = $2
var %mood = $3
This returns the line that starts with the petname you're looking for.

perl search replace is appending not replacing

I have a perl script in a cron that runs every X minutes. It is suppose to find a string and replace it with a string with more data:
s/remote_phonebook.data.1.name =/remote_phonebook.data.1.name = Users/;
I would expect it to look like this:
before:
remote_phonebook.data.1.name =
after:
remote_phonebook.data.1.name = Users
the first time it runs it works fine. However, each additional time it appends to the end of the line so 3 cron jobs later i see:
remote_phonebook.data.1.name = Users Users Users
How can make it so if "Users" doesn't exist, add it, if it exists, ignore?
If each one of these is a new line you could try:
$s =~ s/remote_phonebook\.data\.1\.name =( Users|$)/remote_phonebook.data.1.name = Users/;
If not, please let me know on the comments.
Provide appropriate trailing context, such as only spaces after the = (which won't then do anything when there is Users after the =):
s/remote_phonebook.data.1.name =\s*$/remote_phonebook.data.1.name = Users/;
or even (as suggested by ThisSuitIsBlackNot):
s/(remote_phonebook.data.1.name =)\s*$/$1 Users/;

How can I map UIDs to user names using Perl library functions?

I'm looking for a way of mapping a uid (unique number representing a system user) to a user name using Perl.
Please don't suggest greping /etc/passwd :)
Edit
As a clarification, I wasn't looking for a solution that involved reading /etc/passwd explicitly. I realize that under the hood any solution would end up doing this, but I was searching for a library function to do it for me.
The standard function getpwuid, just like the same C function, gets user information based on its ID. No uses needed:
my ($name) = getpwuid(1000);
print $name,"\n";
Although it eventually reads /etc/passwd file, using standard interfaces is much more clear for other users to see, let alone it saves you some keystrokes.
Read /etc/passwd and hash the UID to login name.
Edit:
$uid = getpwnam($name);
$name = getpwuid($num);
$name = getpwent();
$gid = getgrnam($name);
$name = getgrgid($num);
$name = getgrent();
As you can see, regardless of which one you pick, the system call reads from /etc/passwd (see this for reference)
Actually I would suggest building a hash based on /etc/passwd :-) This should work well as the user ids are required to be unique.

How do I reset my LDAP password from Perl?

My company, like everyone else's, requires password resets from time to time. This is all good and well for security's sake, but I'd like to explore the challenge of resetting it through a script (notably because we can't use our previous 25 passwords; Perl is much quicker about cycling through a list two-dozen deep than my fingers are).
I'm trying to use Perl and Win32::OLE's LDAP connectors to reset my password. I've followed a couple of examples online, and have, briefly:
use strict;
use Win32::OLE;
my $dn = 'cn=name,dc=corp,dc=com';
my $ldap = Win32::OLE->GetObject('LDAP:');
my $ldap_user = $ldap->OpenDSObject('LDAP://' . $dn,'username','password',1);
$ldap_user->SetPassword('mySw337NewPassword');
And all I get for my troubles is:
Win32::OLE(0.1707) error 0x80070005: "Access is denied"
in METHOD/PROPERTYGET "SetPassword" at pw.change.pl line 8
Is this something that can be worked around? I've located the Net::LDAP::Extension::SetPassword module, but no dice there.
Thanks!
Update for Leon (Max, you're next):
You're correct, I should have specified better. I tried Win32::OLE, failed, then separately tried Net::LDAP::Extension::SetPassword and failed even harder.
As for my server: I'm not certain, I'm not the LDAP guy :) By running ->root_dse->get_value('supportedExtension') I can see that the setPassword OID is not set, so maybe it's just not meant to be.
Final props to barneyton!
Final solution:
use strict;
use Win32::OLE;
my $orig_password = 'password123Test';
my $target_password = 'password321Test';
my $dn = 'cn=myname,dc=corp,dc=com';
my $ldap = Win32::OLE->GetObject('LDAP:');
my $ldap_user = $ldap->OpenDSObject('LDAP://'.$dn,'myname',$orig_password,1);
my $tmp_password = '';
for ( my $i = 0; $i < 30; ++$i )
{
$tmp_password = 'password' . $i . 'ABC';
print 'Changing to ' . $tmp_password . "\n";
$ldap_user->ChangePassword($orig_password,$tmp_password);
$orig_password = $tmp_password;
sleep 1;
}
$ldap_user->ChangePassword($tmp_password,$target_password);
When you said you were trying to "reset" your password, I think you really meant change password rather than set password. There is a difference between the two. "SetPassword" requires god/admin privilege since you are setting a user's password to a new value regardless of whether the old password is known, while "ChangePassword" requires the user to actually know the old password. I'm assuming your account does not have admin privilege, else you would not have gotten 0x80070005: "Access is denied"
So instead of:
$ldap_user->SetPassword('mySw337NewPassword');
try this:
$ldap_user->ChangePassword('password', 'mySw337NewPassword');
By the way, I've never done this stuff in perl, so I'm just guessing. Hope this helps you out.
Net::LDAP::Extension::SetPassword doesn't have anything to do with any OLE LDAP object. Either you use Net::LDAP, or you use Win32::OLE->GetObject('LDAP:').
You didn't mention what server you're using. Setting passwords requires an extension to LDAP, so that is relevant.
Another thing to keep in mind is Active Directory does not let you set passwords unless you bind to port 636 using LDAPS.
You could try to write the value to userPassword which would be a password reset, and you might not have rights to do that.
Otherwise you could try in one operation (LDIF would show it as separated by a single dash on a line) remove the value of the old password and then add the value of the new password. That would be a password change event.