line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package Citrix::SessOp; |
2
|
|
|
|
|
|
|
#use strict; |
3
|
|
|
|
|
|
|
#use warnings; |
4
|
|
|
|
|
|
|
|
5
|
|
|
|
|
|
|
our $VERSION = "0.25"; |
6
|
|
|
|
|
|
|
|
7
|
|
|
|
|
|
|
=head1 NAME |
8
|
|
|
|
|
|
|
|
9
|
|
|
|
|
|
|
Citrix::SessOp - Disconnect or Logoff from an existing Citrix Session. |
10
|
|
|
|
|
|
|
|
11
|
|
|
|
|
|
|
=head1 DESCRIPTION |
12
|
|
|
|
|
|
|
|
13
|
|
|
|
|
|
|
Control Citrix session state by launching associated command line utilities. |
14
|
|
|
|
|
|
|
The module user should take care of gaining authority to (by host/user, |
15
|
|
|
|
|
|
|
whatever) execute these commands successfully on Citrix Farm as the |
16
|
|
|
|
|
|
|
current process runtime user (It seems Citrix commands and associated protocol map the user |
17
|
|
|
|
|
|
|
1-to-1 to the server end). Lacking this permission the commands will fail. |
18
|
|
|
|
|
|
|
|
19
|
|
|
|
|
|
|
Module aims to provide proper return values and error messages |
20
|
|
|
|
|
|
|
when things fail, but this is not a substitute for first taking care of |
21
|
|
|
|
|
|
|
of proper permissions (for lauching Citrix commands) with your local Citrix Admin. |
22
|
|
|
|
|
|
|
|
23
|
|
|
|
|
|
|
=head1 SYNOPSIS |
24
|
|
|
|
|
|
|
|
25
|
|
|
|
|
|
|
use Citrix::SessOp; |
26
|
|
|
|
|
|
|
my $fms = Citrix::getfarms('idx' => 1); |
27
|
|
|
|
|
|
|
my $farmctx = $fms->{'cairo'}; |
28
|
|
|
|
|
|
|
my $csop = Citrix::SessOp->new($farmctx); |
29
|
|
|
|
|
|
|
|
30
|
|
|
|
|
|
|
# Disconnect (leaves session idle, to "returnable" state) |
31
|
|
|
|
|
|
|
$err = $csop->disconnect("the-cx-host-12:8879"); |
32
|
|
|
|
|
|
|
|
33
|
|
|
|
|
|
|
# Log Off Completely (Terminating UNIX X-Windows session) |
34
|
|
|
|
|
|
|
$err = $csop->logoff("the-cx-host-12:8879"); |
35
|
|
|
|
|
|
|
|
36
|
|
|
|
|
|
|
=head1 METHODS |
37
|
|
|
|
|
|
|
|
38
|
|
|
|
|
|
|
=head2 $csop = Citrix::SessOp->new($farmctx); |
39
|
|
|
|
|
|
|
|
40
|
|
|
|
|
|
|
Create a new Citrix session operation by L context ($farmctx). |
41
|
|
|
|
|
|
|
The ops available later are disconnect() / logoff() (See method docs on each for details). |
42
|
|
|
|
|
|
|
Return session operation instance. |
43
|
|
|
|
|
|
|
|
44
|
|
|
|
|
|
|
=cut |
45
|
|
|
|
|
|
|
sub new { |
46
|
0
|
|
|
0
|
1
|
|
my ($class, $fc) = @_; |
47
|
|
|
|
|
|
|
#my ($h, $sid) = split(/:/, $hostsess); |
48
|
0
|
0
|
|
|
|
|
if (!$fc) {return(undef);} |
|
0
|
|
|
|
|
|
|
49
|
0
|
|
|
|
|
|
return(bless({ 'fc' => $fc}, $class)); # 'hs' => $hostsess, |
50
|
|
|
|
|
|
|
} |
51
|
|
|
|
|
|
|
|
52
|
|
|
|
|
|
|
|
53
|
|
|
|
|
|
|
=head2 $err = $cop->disconnect("the-cx-host-12:8879"); |
54
|
|
|
|
|
|
|
|
55
|
|
|
|
|
|
|
Disconnect a Citrix session By Host Session ID ($hostsess in format "$hostname:$sessid"). |
56
|
|
|
|
|
|
|
Disconnect persists the session state (leaves applications in the state they were before disconnect). |
57
|
|
|
|
|
|
|
Return 0 for success, 1 (and up) for errors. |
58
|
|
|
|
|
|
|
|
59
|
|
|
|
|
|
|
=cut |
60
|
|
|
|
|
|
|
|
61
|
|
|
|
|
|
|
sub disconnect { |
62
|
0
|
|
|
0
|
1
|
|
my ($op, $hostsess) = @_; |
63
|
0
|
|
|
|
|
|
opexec($op, $hostsess, 'ctxdisconnect'); |
64
|
|
|
|
|
|
|
|
65
|
|
|
|
|
|
|
} |
66
|
|
|
|
|
|
|
|
67
|
|
|
|
|
|
|
=head2 $err = $cop->logoff("the-cx-host-12:8879"); |
68
|
|
|
|
|
|
|
|
69
|
|
|
|
|
|
|
Logoff from a Citrix session By Host Session ID ($hostsess in format "$hostname:$sessid"). |
70
|
|
|
|
|
|
|
Logging off completely destroys the session state (closes apps and terminates X-Windows session). |
71
|
|
|
|
|
|
|
Return 0 for success, 1 (and up) for errors. |
72
|
|
|
|
|
|
|
|
73
|
|
|
|
|
|
|
=cut |
74
|
|
|
|
|
|
|
sub logoff { |
75
|
0
|
|
|
0
|
1
|
|
my ($op, $hostsess) = @_; |
76
|
0
|
|
|
|
|
|
opexec($op, $hostsess, 'ctxlogoff'); |
77
|
|
|
|
|
|
|
} |
78
|
|
|
|
|
|
|
|
79
|
|
|
|
|
|
|
# Internal accessor to Get/Set Farm context of a Citrix Operation. |
80
|
|
|
|
|
|
|
sub fc { |
81
|
0
|
|
|
0
|
0
|
|
my ($op, $fc) = @_; |
82
|
0
|
0
|
|
|
|
|
if ($fc) {$op->{'fc'} = $fc;} |
|
0
|
|
|
|
|
|
|
83
|
0
|
|
|
|
|
|
$op->{'fc'}; |
84
|
|
|
|
|
|
|
} |
85
|
|
|
|
|
|
|
|
86
|
|
|
|
|
|
|
# Internal method for executing Citrix Operation by launching associated command $cmd. |
87
|
|
|
|
|
|
|
# Not part of public API, do not use this directly. Please use the wrapper methods disconnect() and |
88
|
|
|
|
|
|
|
# logoff() as operations. |
89
|
|
|
|
|
|
|
# Return 0 for success, 1 for failure. |
90
|
|
|
|
|
|
|
sub opexec { |
91
|
0
|
|
|
0
|
0
|
|
my ($op, $hostsess, $cmd) = @_; |
92
|
|
|
|
|
|
|
#my ($h, $sid) = split(/:/, $hostsess); |
93
|
|
|
|
|
|
|
#my ($h, $sid) = split(/:/, $op->{'hs'}); |
94
|
0
|
|
|
|
|
|
my $tout = $Citrix::touts->{'op'}; # 5; |
95
|
0
|
|
|
|
|
|
my $fc = $op->fc(); |
96
|
|
|
|
|
|
|
#if (!$fc) {die("No Farm Context for operation");} |
97
|
0
|
|
|
|
|
|
my $mh = $fc->masterhost(); # OLD: {'mh'} |
98
|
|
|
|
|
|
|
#if (!$mh) {die("No Master host for Farm");} |
99
|
0
|
0
|
|
|
|
|
if (!$Citrix::binpath) {die("Citrix binary path is NOT set !!!");} |
|
0
|
|
|
|
|
|
|
100
|
0
|
|
|
|
|
|
my $clcmd = "$Citrix::binpath/$cmd"; |
101
|
|
|
|
|
|
|
# Allow configuring Command to be local |
102
|
0
|
|
|
|
|
|
my $wcmd = "rsh $mh $clcmd $hostsess"; |
103
|
|
|
|
|
|
|
#OLD:system($wcmd); |
104
|
0
|
|
|
|
|
|
eval { |
105
|
0
|
|
|
0
|
|
|
local $SIG{'ALRM'} = sub {die("Error Controlling session '$hostsess' within timelimit ($tout s.)\n");}; |
|
0
|
|
|
|
|
|
|
106
|
0
|
|
|
|
|
|
alarm($tout); |
107
|
0
|
|
|
|
|
|
$op->{'msg'} = `$wcmd`; |
108
|
|
|
|
|
|
|
}; |
109
|
0
|
|
|
|
|
|
alarm(0); |
110
|
0
|
0
|
0
|
|
|
|
if ($? || $@) {$op->{'msg'} = "Error $? / $! ($op->{'msg'}) Executing Session command '$wcmd'\n";return(1);} |
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
111
|
|
|
|
|
|
|
#else {$op->{'msg'} = "$op->{'msg'}";} |
112
|
|
|
|
|
|
|
# Consider the Error Indicators (Any others ?) |
113
|
0
|
0
|
|
|
|
|
if ($op->{'msg'} =~ /^Access/) {return(1);} |
|
0
|
|
|
|
|
|
|
114
|
|
|
|
|
|
|
# If no message is gotten expect it to be successful (is this correct assumption ?). |
115
|
|
|
|
|
|
|
# One of commands does not return any message |
116
|
0
|
0
|
|
|
|
|
if (!$op->{'msg'}) {$op->{'msg'} = "Operation Successful";} |
|
0
|
|
|
|
|
|
|
117
|
0
|
|
|
|
|
|
return(0); |
118
|
|
|
|
|
|
|
} |
119
|
|
|
|
|
|
|
|
120
|
|
|
|
|
|
|
1; |