#! /usr/local/bin/perl
# The previous line (first line in file) needs to point
# to the system path for Perl on Unix/Linux machines.
# Under NT, this line is usually unnecessary...unless
# you are running Apache for NT.
#####################################################
#####################################################
# RealTimeAide - See Accompanying Version.txt file
# For Copyright and version information
#
# File Revision: 05/02/2003
#####################################################
####################################################
# start_client_process.pl
#
# Performs two functions: First, it determines
# what service is being que'd and loads an HTML
# page that displays the active helpers for that
# service. After the client selects one and submits,
# it signals the helper that a chat is being requested
# then loads the main client chat form with the
# helper's default greeting.
####################################################
$|++;
require "rta_function_lib.pl";
my $options = parse_query_params();
my $function = $options->{'function'};
if ($function eq "start") {
load_client_start_page(retrieve_helper_list());
} elsif ($function eq "chat") {
start_chat_process();
} else {
load_error_page("Sorry we couldn't be of assistance, but we couldn't determine your need.");
}
exit;
### Subroutines start here ###
######################################################
# start_chat_process() subroutine
#
# This is the main function of this application.
# It orchastrates the process behind setting-up
# the chat.
######################################################
sub start_chat_process {
my $helper = html_decoder($options->{'helper'}) or 0;
my $session_name = get_session_name($helper);
my $user_ip = $ENV{'REMOTE_ADDR'};
my $helper_data = get_default_text($helper);
my ($helper_name, $helper_text) = @$helper_data;
my $client_domain = get_client_domain($user_ip);
if (!$client_domain) {
$client_domain = $user_ip;
}
my $response = notify_helper($helper, $session_name, $client_domain);
if ($response) {
$response = create_session_log($session_name, $helper_name, $helper_text);
if ($response) {
load_client_chat_window($session_name);
} else {
load_error_page("Sorry, we are unable to assist you at this time. Please try back in a few minutes.");
}
} else {
# Oops, we times out. better crank out the error page!
load_error_page("Sorry, we are unable to assist you at this time. Please try back in a few minutes.");
}
}
######################################################
# get_client_domain() subroutine
#
# This subroutine retrieves the domain name matching
# the IP of the requesting client. Only returns
# the first of many possible matches.
######################################################
sub get_client_domain {
my $user_ip = shift;
my $rtn_str = 0;
$/ = "\n";
open(DOMAINS, $DOMAIN_FILE);
my @domains = ;
close(DOMAINS);
my ($ip, $dn, $ts) = "";
foreach my $domain (@domains) {
chomp($domain);
($ip, $dn, $ts) = split(/\|/, $domain);
if ($ip eq $user_ip) {
$rtn_str = $dn;
}
}
return $rtn_str;
}
######################################################
# get_user_name() subroutine
#
# This subroutine retrieves the user's name from
# the HTML page. If the user didn't enter a name,
# the function returns a blank field.
######################################################
sub get_user_name {
my $user = $options->{'name'};
my ($part, $name) = "";
if (!$user) {
$name = "";
} else {
$user = lc $user;
$user = html_decoder($user);
my @name = split(/ /, $user);
foreach $part (@name) {
$part = ucfirst $part;
$name .= $part . '_';
}
$name =~ s/_$//;
}
return $name;
}
######################################################
# load_client_chat_window() subroutine
#
# This subroutine creates the frameset required
# to start the chat session from the client's side.
######################################################
sub load_client_chat_window {
my $session = shift;
my $user = get_user_name();
if ($user eq "") {
$user = "You";
}
my $HTML = qq~
Attorney Resume Live Chat !!
~;
display_html($HTML);
}
######################################################
# notify_helper() subroutine
#
# This subroutine notifies the selected helper that
# he/she has a user request for a chat.
######################################################
sub notify_helper {
my ($helper, $session_name, $domain_name) = @_;
my $sleep_seconds = 0;
my $max_sleep = 15;
my $path = $DATA_DIR;
my $LOCK_EX = 2; # Exclusive lock mode.
my $user = get_user_name();
if ($user eq "") {
$user = "Client";
}
my $write_data = "$session_name\|$domain_name\|$user";
my $base_file_name = "$path/incomming-$helper";
my $file_number = 0;
my $data_file = "";
while ($sleep_seconds < $max_sleep) {
# Increment the file number. Up to 4 incomming
# chat sessions allowed per helper.
$file_number++;
# $data_file composed of the base file name and
# the count in $file_number
$data_file = $base_file_name . "-" . $file_number;
if (!-e $data_file) {
# Test to see if the filename exists. If not,
# exit the while loop and do something.
last;
} elsif (-e $data_file && $file_number < 4) {
# Else, if the file exists, and the count
# in $file_number is less than 4, try
# the next number.
next;
} else {
# Well, the file exists AND the count in
# $file_number exceeds 4. Reset the count
# to zero and sleep for a second, then
# start over.
$file_number = 0;
sleep(1);
$sleep_seconds++;
}
}
# The file was finally opened.
if ($sleep_seconds < $max_sleep) {
open(DATA, ">>$data_file");
flock(DATA, $LOCK_EX); # Request an exclusive file lock
print DATA $write_data; # Write the incomming data to the file
print DATA "\n"; # Add a linefeed
close(DATA); # Close the file and free the lock.
return 1;
} else {
return 0;
}
}
######################################################
# create_session_log() subroutine
#
# This subroutine creates the actual session log,
######################################################
sub create_session_log {
my ($session_name, $helper_name, $helper_text) = @_;
my $sep_character = ">";
my $path = $DATA_DIR;
my $LOCK_EX = 2; # Exclusive lock mode.
if ($use_colon_sep == 1) {
$sep_character = ":";
}
my $write_data = "$helper_name$sep_character $helper_text";
my $file_name_trailer = "A";
my $data_file = "$path/$session_name";
if (-e $data_file) {
$data_file .= $file_name_trailer;
while (-e $data_file) {
$data_file++;
}
}
open(DATA, ">>$data_file");
flock(DATA, $LOCK_EX); # Request an exclusive file lock
print DATA $write_data; # Write the incomming data to the file
print DATA "\n"; # Add a linefeed
close(DATA); # Close the file and free the lock.
##################################
# RWS Mod #
# 09/22/2001 #
# Add another file to keep track #
# of the number of writes to #
# the session file. #
##################################
$data_file =~ s/\.ses$/\.num/; # Change the extension to .num
my $session_num = 1;
open(DATA, ">$data_file");
flock(DATA, $LOCK_EX); # Request an exclusive file lock
print DATA $session_num; # Save the initial write number
close(DATA); # Close the file and free the lock
return 1;
}
######################################################
# get_default_text() subroutine
#
# This subroutine retrieves the selected helper's
# default greeting.
#
# Inputs:
# $helper - The selected helper's id number
######################################################
sub get_default_text {
my $helper = shift;
my ($email, $ln, $fn, $hi_str) = "";
my $temprs = $/;
$/ = "\n"; # Record sep. to "linefeed" mode.
my $filename = $HELPER_FILE;
my $rtn_str = "";
my $name_str = "";
if (-e $filename) {
open(DATA, "$filename");
while () {
chomp; # no newline
s/#.*//; # no comments
s/^\s+//; # no leading white space
s/\s+$//; # no trailing white space
next unless length; # anything left?
($email, $ln, $fn, $hi_str) = split(/\|/, $_);
if ($email eq $helper) {
if ($fn ne "") {
$name_str = $fn;
} else {
$name_str = $ln;
}
$name_str = "HELPER:$name_str";
$rtn_str = [$name_str, $hi_str . "\|"];
last;
}
}
undef $/; # File Slurp mode.
}
close(DATA);
return $rtn_str;
}
######################################################
# get_session_name() subroutine
#
# Creates a new session name based on:
# RTA-service number-helper id-packed date-time (ie: 20000215022520)
# ex: RTA-12345-27-20000215024258
#
# Inputs:
# $helper - The helper's id
# Returns:
# $session_name - New session Name.
######################################################
sub get_session_name {
my $helper = shift;
my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time);
$year += 1900;
$mon +=1;
$mon = "0" . $mon unless length $mon > 1;
$mday = "0" . $mday unless length $mday > 1;
$hour = "0" . $hour unless length $hour > 1;
$min = "0" . $min unless length $min > 1;
$sec = "0" . $sec unless length $sec > 1;
my $session_name = "RTA-$helper-$year$mon$mday$hour$min$sec.ses";
return $session_name;
}
######################################################
# load_client_start_page() subroutine
#
# Loads the Client start HTML page. Substitutes
# the helper
######################################################
sub load_client_start_page {
my $helper_list = shift;
my ($row, $id, $name, $select) = "";
my $company_avail = get_availability_times();
my $co_name = $company_avail->{'COMPANY NAME'};
my $helpers_available = scalar @$helper_list;
if ($helpers_available < 1) {
my $time_start = $company_avail->{'HELPER START TIME'};
my $time_stop = $company_avail->{'HELPER STOP TIME'};
my $week_start = $company_avail->{'WEEK STARTS'};
my $week_end = $company_avail->{'WEEK ENDS'};
my $cc = $company_avail->{'COUNTRY'};
my $tz = $company_avail->{'TIME ZONE'};
my $email = $company_avail->{'DEFAULT EMAIL'};
my $days_available = "";
if (!$week_end) {
$days_available = $week_start;
} else {
$days_available = "$week_start - $week_end";
}
my $available = "";
undef $/; # file slurp mode.
open(DATA, "$HTML_DIR/RTA/client_no_helper_message.html");
my $HTML = ;
close(DATA);
if ($use_availability_times) {
$available = qq(
Check back with us soon or contact us by e-mail at: $email
)
}
$HTML =~ s//$available/ig;
display_html($HTML);
exit;
} else {
$helper_select = qq();
undef $/; # file slurp mode.
open(DATA, "$HTML_DIR/RTA/rta_client_request_page.html");
my $HTML = ;
close(DATA);
$HTML =~ s//$helper_select/ig;
$HTML =~ s//$co_name/ig;
display_html($HTML);
exit;
}
}
######################################################
# retrieve_helper_list() subroutine
#
# Retrieves a list of helper names
# from the company identified by the service
# element on the start_helper link.
#
# Returns:
# $results - anonymous array of arrays containing
# the list of helper names and id's.
######################################################
sub retrieve_helper_list {
my @return_data = ();
my @helpers_online = ();
my $sessions = ();
my $helper_email = "";
my $helper_name = "";
my $helper_online = "";
my $available_helpers = 0;
my $sessions_in_progress = 0;
opendir(DATADIR, $DATA_DIR);
my @helper_names = readdir(DATADIR);
closedir(DATADIR);
shift(@helper_names);
shift(@helper_names);
foreach $helper_online (@helper_names) {
if ($helper_online =~ /.hpr$/i) {
# Get a list of helper names and
# email addresses of the helpers
# currently on-line:
open(DATA, "$DATA_DIR/$helper_online");
$helper_email = ;
close(DATA);
chomp($helper_email);
$helper_online =~ s/\.hpr//;
$helper_online =~ s/_/ /;
push(@helpers_online, [$helper_email, $helper_online]);
} elsif ($helper_online =~ /.ses$/i) {
# Get sessions in progress
my ($rta, $helper_data, $date) = split(/-/, $helper_online);
push(@sessions, $helper_data);
}
}
if (scalar @helpers_online > 0) {
# There are helpers online, lets get them:
if (scalar @sessions < 1) {
# No sessions in progress, just get the
# helpers online:
return \@helpers_online;
} else {
# There are session files in the directory,
# Loop through the @helpers_online array and
# compare the entries to the entries in the
# @sessions array. If the amound of sessions
# for each helper is less than the value in
# $max_chats, add that helper's data to the
# @return_data array:
foreach $helper_online (@helpers_online) {
$sessions_in_progress = 0;
($helper_email, $helper_name) = @$helper_online;
foreach my $session (@sessions) {
if ($session eq $helper_email) {
$sessions_in_progress++;
}
}
if ($sessions_in_progress < $max_chats) {
push(@return_data, [$helper_email, $helper_name]);
}
}
return \@return_data;
}
} else {
return 0;
}
}
######################################################
# get_availability_times() subroutine
#
# Retrieves the on-line start, stop, time zone
# and days string for the selected company.
######################################################
sub get_availability_times {
my $filename = $COMPANY_FILE;
my $temprs = $/;
$/ = "\n"; # Record sep. to "linefeed" mode.
my %config_data = {}; # Create "my" variable and undef it.
my ($key, $value) = ""; # Variables for the hash's key-value pair.
if (-e $filename) {
open(CONF, "$filename");
while () {
chomp; # no newline
s/#.*//; # no comments
s/^\s+//; # no leading white space
s/\s+$//; # no trailing white space
next unless length; # anything left?
($key, $value) = split(/\s*=\s*/, $_, 2);
$config_data->{$key} = $value;
}
close(CONF);
$/ = $temprs; # Set record separator back.
return $config_data; # Scalar with reference to anonymous hash.
} else {
return 0;
}
}