#!/usr/bin/perl
# wcs 8/25/2005
# dirinput.txml file calls this CGI with the 'fn' and 'sn' GET variables
# output is a Cisco IP Phone MENU object which dials the phone upon selection
# * modified 10/7/2005 - now gets affiliation and "department" to make
# identification of directory entries easier
# * modified 10/27/2005 - this version only returns entries that contain
# a telephone number
# * modified 12/21/2005 - now provides better user interaction and
# includes a toggle to enable or disable must-have-DN property
use strict;
use CGI;
use Net::LDAP;
# SET THESE VARIABLES
my $inputPage = "http://webserver/ph/dirinput.txml"; # calling page
my $mustHaveListing = 1; # only return entries that have associated DNs
# (set to 1 for default behavior)
# do this first
print "Content-type: text/xml\n\n";
# Define variables
# ----------------
# LDAP directory to contact
my $directoryURL = "ldap.psu.edu";
# Portion of the directory we'll be searching
my $searchBase = "dc=psu,dc=edu";
# CGI vars
my $q = new CGI;
my $cgi_fn = $q->param('fn');
my $cgi_sn = $q->param('sn');
# The attributes (and their associated values) that we wish to
# search for in the directory.
my ($fn, $sn);
if (defined $cgi_fn) {
$fn = $cgi_fn;
} else {
$fn = "";
}
if (defined $cgi_sn) {
$sn = $cgi_sn;
} else {
errorNoLastname();
}
my $searchFilter = "(&(sn=$sn*)(|(edupersonNickname=$fn*)(givenName=$fn*)))";
# The attributes we'd like to have returned for each entry
#
# (Doing this is entirely optional; it simply reduces the
# volume of data returned by excluding attributes that we're
# not interested in receiving.)
my $attributesToReturn = [
'displayName',
'mail',
'telephoneNumber',
'givenName',
'sn',
'eduPersonPrimaryAffiliation',
'psCurriculum',
'psAdminArea'
];
# Connect to the directory
# ------------------------
# Open a connection to the directory
my $ldap = Net::LDAP->new($directoryURL, timeout => '20') # as struct
or errorUnavailable();
# Make an anonyous bind to the directory
$ldap->bind ;
# Perform a search
# ----------------
my $searchResultsObject = $ldap->search
(
base => $searchBase, # Note the comma here
filter => $searchFilter, # and here
# Return only a limited set of attributes from
# the search, *if* we've defined such a set above
attrs => $attributesToReturn
);
# If there is a result code (indicating an error),
# display an error message
if ($searchResultsObject->code) {
print STDERR $searchResultsObject->error;
if ($searchResultsObject->code == 4) { # LDAP_SIZELIMIT_EXCEEDED
errorTooMany();
} else {
errorNoResults();
}
}
# Disconnect from the directory
# -----------------------------
$ldap->unbind;
# Work with the data returned from the search
# -------------------------------------------
my $countOfEntriesReturned = $searchResultsObject->count;
# IP Phone can only produce menus of 100 items or fewer
if ($countOfEntriesReturned > 100) {
errorTooMany();
}
# Begin output
print "\n";
# Cycle through each of the directory entries returned from the
# search, and extract and print the values of selected attributes
# of each entry
# sort on last name, then first name
# keep count of number of entries processed
my $counter = 0;
foreach my $entry ($searchResultsObject->sorted('sn','givenName'))
{
# Look at each of the 'entry' objects returned from the search
# Initialize each variable each time through the loop
my $displayName = "";
my $affil = "";
my $department = "";
my $phoneNumber = "";
my $dialNum = "";
$phoneNumber = $entry->get_value('telephoneNumber');
if ($mustHaveListing && !$phoneNumber) { # is a DN required? is there one?
next; # if not, don't process this one
}
$counter++; # we're still here, so add one to process
# Extract the values from selected attributes
$displayName = lc($entry->get_value('displayname'));
$displayName =~ s/^(\w)/uc $1/e;
$displayName =~ s/ (\w)/" " . uc $1/eg;
$affil = $entry->get_value('eduPersonPrimaryAffiliation');
#$affil =~ s/^(\w)/uc $1/e;
#$affil =~ s/ (\w)/" " . uc $1/eg;
$affil =~ s/FACULTY/Fac/;
$affil =~ s/STAFF/Stf/;
$affil =~ s/EMPLOYEE/Empl/;
$affil =~ s/STUDENT/Stu/;
$affil =~ s/RETIREE/Ret/;
$affil =~ s/EMERITUS/Emer/;
$affil =~ s/MEMBER/Affil/;
if ($affil eq "Stu") {
$department = lc($entry->get_value('psCurriculum'));
$department =~ s/^(\w)/uc $1/e;
$department =~ s/ (\w)/" " . uc $1/eg;
} elsif ($affil eq "Affil") {
$department = $entry->get_value('mail');
} else {
$department = lc($entry->get_value('psAdminArea'));
$department =~ s/^(\w)/uc $1/e;
$department =~ s/ (\w)/" " . uc $1/eg;
}
print "";
}
print "Search returned $counter";
if ($counter == 1) {
print " entry\n";
} else {
print " entries\n";
}
if ($counter == 0) {
print <
Back
$inputPage
2
Exit
SoftKey:Exit
3
Back to search again or Exit
EOF
} else {
print <
Dial
SoftKey:Select
1
Back
$inputPage
2
Exit
SoftKey:Exit
3
Select a number to dial
EOF
}
print "\n";
exit;
# -----------------------
# the following error subs terminate processing and exit after displaying
# the error message to the phone
sub errorNoResults()
{
print <
No Information
No information was returned from your search, or an error occurred.
Back
$inputPage
2
Exit
SoftKey:Exit
3
Back to search again or Exit
EOF
exit;
}
sub errorNoLastname()
{
print <
Last Name Required
Please enter some or all of the person's last name into the Last field. This is a required field.
Back
$inputPage
2
Exit
SoftKey:Exit
3
Back to search again or Exit
EOF
exit;
}
sub errorTooMany()
{
print <
Too Many Results
Over 100 results returned. Please narrow your search by specifying a full last name and, optionally, some or all of the first name.
Back
$inputPage
2
Exit
SoftKey:Exit
3
EOF
exit;
}
sub errorUnavailable()
{
print STDERR "$@";
print <
Service unavailable
The search service is temporarily unavailable. Please try again later.
Exit
SoftKey:Exit
3
EOF
exit;
}