line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package Flexnet::lmutil; |
2
|
|
|
|
|
|
|
|
3
|
2
|
|
|
2
|
|
41237
|
use 5.006; |
|
2
|
|
|
|
|
8
|
|
4
|
2
|
|
|
2
|
|
12
|
use strict; |
|
2
|
|
|
|
|
3
|
|
|
2
|
|
|
|
|
42
|
|
5
|
2
|
|
|
2
|
|
9
|
use warnings; |
|
2
|
|
|
|
|
7
|
|
|
2
|
|
|
|
|
63
|
|
6
|
2
|
|
|
2
|
|
1434
|
use File::Which; |
|
2
|
|
|
|
|
1893
|
|
|
2
|
|
|
|
|
4308
|
|
7
|
|
|
|
|
|
|
|
8
|
|
|
|
|
|
|
=head1 NAME |
9
|
|
|
|
|
|
|
|
10
|
|
|
|
|
|
|
Flexnet::lmutil - Convenient OO-interface for Flexnet license server utility lmutil |
11
|
|
|
|
|
|
|
|
12
|
|
|
|
|
|
|
=head1 VERSION |
13
|
|
|
|
|
|
|
|
14
|
|
|
|
|
|
|
Version 1.3 |
15
|
|
|
|
|
|
|
|
16
|
|
|
|
|
|
|
=cut |
17
|
|
|
|
|
|
|
|
18
|
|
|
|
|
|
|
our $VERSION = '1.3'; |
19
|
|
|
|
|
|
|
|
20
|
|
|
|
|
|
|
=head1 DESCRIPTION |
21
|
|
|
|
|
|
|
|
22
|
|
|
|
|
|
|
Flexnet::lmutil is a small wrapper around the Flexnet license server utility lmutil, |
23
|
|
|
|
|
|
|
currently implementing the sub-functions lmstat and lmremove. The module parses the |
24
|
|
|
|
|
|
|
output of lmstat and returns an easy-to-use data structure. This makes it easy to |
25
|
|
|
|
|
|
|
work further with lmstat output for e.g. web pages, monitoring plugins etc. |
26
|
|
|
|
|
|
|
|
27
|
|
|
|
|
|
|
|
28
|
|
|
|
|
|
|
=head1 SYNOPSIS |
29
|
|
|
|
|
|
|
|
30
|
|
|
|
|
|
|
use Flexnet::lmutil; |
31
|
|
|
|
|
|
|
|
32
|
|
|
|
|
|
|
my $lmutil = new Flexnet::lmutil ( |
33
|
|
|
|
|
|
|
lm_license_path => 'port@host', |
34
|
|
|
|
|
|
|
... |
35
|
|
|
|
|
|
|
|
36
|
|
|
|
|
|
|
); |
37
|
|
|
|
|
|
|
|
38
|
|
|
|
|
|
|
$status = $lmutil->lmstat ( |
39
|
|
|
|
|
|
|
feature => 'feature', |
40
|
|
|
|
|
|
|
|
41
|
|
|
|
|
|
|
OR |
42
|
|
|
|
|
|
|
|
43
|
|
|
|
|
|
|
daemon => 'daemon', |
44
|
|
|
|
|
|
|
|
45
|
|
|
|
|
|
|
OR |
46
|
|
|
|
|
|
|
|
47
|
|
|
|
|
|
|
'all' |
48
|
|
|
|
|
|
|
); |
49
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
$lmutil->lmremove ( |
51
|
|
|
|
|
|
|
feature => 'feature', |
52
|
|
|
|
|
|
|
serverhost => 'host', |
53
|
|
|
|
|
|
|
port => 'port', |
54
|
|
|
|
|
|
|
handle => 'handle' |
55
|
|
|
|
|
|
|
); |
56
|
|
|
|
|
|
|
|
57
|
|
|
|
|
|
|
=head1 DETAILS |
58
|
|
|
|
|
|
|
|
59
|
|
|
|
|
|
|
Possible arguments for the constructor are: |
60
|
|
|
|
|
|
|
|
61
|
|
|
|
|
|
|
=over 4 |
62
|
|
|
|
|
|
|
|
63
|
|
|
|
|
|
|
=item C |
64
|
|
|
|
|
|
|
|
65
|
|
|
|
|
|
|
either the full pathname of the license file or the string C |
66
|
|
|
|
|
|
|
or even C... |
67
|
|
|
|
|
|
|
|
68
|
|
|
|
|
|
|
=item C |
69
|
|
|
|
|
|
|
|
70
|
|
|
|
|
|
|
show command line call |
71
|
|
|
|
|
|
|
|
72
|
|
|
|
|
|
|
=item C |
73
|
|
|
|
|
|
|
|
74
|
|
|
|
|
|
|
textfile containing lmstat output (for testing), does not run lmstat |
75
|
|
|
|
|
|
|
|
76
|
|
|
|
|
|
|
=back |
77
|
|
|
|
|
|
|
|
78
|
|
|
|
|
|
|
Possible arguments for C are: |
79
|
|
|
|
|
|
|
|
80
|
|
|
|
|
|
|
=over 4 |
81
|
|
|
|
|
|
|
|
82
|
|
|
|
|
|
|
=item C |
83
|
|
|
|
|
|
|
|
84
|
|
|
|
|
|
|
get info about feature usage |
85
|
|
|
|
|
|
|
|
86
|
|
|
|
|
|
|
=item C |
87
|
|
|
|
|
|
|
|
88
|
|
|
|
|
|
|
get info about daemon usage |
89
|
|
|
|
|
|
|
|
90
|
|
|
|
|
|
|
=item C |
91
|
|
|
|
|
|
|
|
92
|
|
|
|
|
|
|
get info about usage of all daemons and features |
93
|
|
|
|
|
|
|
|
94
|
|
|
|
|
|
|
=back |
95
|
|
|
|
|
|
|
|
96
|
|
|
|
|
|
|
C returns a hash reference with the following keys: |
97
|
|
|
|
|
|
|
|
98
|
|
|
|
|
|
|
=over 4 |
99
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
=item * C |
101
|
|
|
|
|
|
|
|
102
|
|
|
|
|
|
|
=item * C |
103
|
|
|
|
|
|
|
|
104
|
|
|
|
|
|
|
=item * C |
105
|
|
|
|
|
|
|
|
106
|
|
|
|
|
|
|
=back |
107
|
|
|
|
|
|
|
|
108
|
|
|
|
|
|
|
B points to another structure like |
109
|
|
|
|
|
|
|
|
110
|
|
|
|
|
|
|
'server' => { |
111
|
|
|
|
|
|
|
'elba.uni-paderborn.de' => { |
112
|
|
|
|
|
|
|
'ok' => 1, |
113
|
|
|
|
|
|
|
'status' => 'UP' |
114
|
|
|
|
|
|
|
} |
115
|
|
|
|
|
|
|
}, |
116
|
|
|
|
|
|
|
|
117
|
|
|
|
|
|
|
B points to a structure like |
118
|
|
|
|
|
|
|
|
119
|
|
|
|
|
|
|
'vendor' => { |
120
|
|
|
|
|
|
|
'cdslmd' => { |
121
|
|
|
|
|
|
|
'ok' => 1, |
122
|
|
|
|
|
|
|
'status' => 'UP v11.11', |
123
|
|
|
|
|
|
|
'version' => '11.11' |
124
|
|
|
|
|
|
|
} |
125
|
|
|
|
|
|
|
} |
126
|
|
|
|
|
|
|
|
127
|
|
|
|
|
|
|
B points to a structure like |
128
|
|
|
|
|
|
|
|
129
|
|
|
|
|
|
|
'feature' => { |
130
|
|
|
|
|
|
|
'MATLAB' => { |
131
|
|
|
|
|
|
|
'reservations' => [ |
132
|
|
|
|
|
|
|
{ |
133
|
|
|
|
|
|
|
'reservations' => '1', |
134
|
|
|
|
|
|
|
'group' => 'etechnik-labor', |
135
|
|
|
|
|
|
|
'type' => 'HOST_GROUP' |
136
|
|
|
|
|
|
|
} |
137
|
|
|
|
|
|
|
], |
138
|
|
|
|
|
|
|
'issued' => '115', |
139
|
|
|
|
|
|
|
'used' => '36', |
140
|
|
|
|
|
|
|
'users' => [ |
141
|
|
|
|
|
|
|
{ |
142
|
|
|
|
|
|
|
'serverhost' => 'dabu.uni-paderborn.de', |
143
|
|
|
|
|
|
|
'startdate' => 'Wed 8/12 17:18', |
144
|
|
|
|
|
|
|
'port' => '27000', |
145
|
|
|
|
|
|
|
'licenses' => 1, |
146
|
|
|
|
|
|
|
'display' => 'bessel', |
147
|
|
|
|
|
|
|
'host' => 'bessel', |
148
|
|
|
|
|
|
|
'handle' => '4401', |
149
|
|
|
|
|
|
|
'user' => 'hangmann' |
150
|
|
|
|
|
|
|
}, |
151
|
|
|
|
|
|
|
] |
152
|
|
|
|
|
|
|
}, |
153
|
|
|
|
|
|
|
}, |
154
|
|
|
|
|
|
|
... |
155
|
|
|
|
|
|
|
|
156
|
|
|
|
|
|
|
=head1 AUTHOR |
157
|
|
|
|
|
|
|
|
158
|
|
|
|
|
|
|
Christopher Odenbach, C<< >> |
159
|
|
|
|
|
|
|
|
160
|
|
|
|
|
|
|
=head1 BUGS |
161
|
|
|
|
|
|
|
|
162
|
|
|
|
|
|
|
Please report any bugs or feature requests to C, or through |
163
|
|
|
|
|
|
|
the web interface at L. I will be notified, and then you'll |
164
|
|
|
|
|
|
|
automatically be notified of progress on your bug as I make changes. |
165
|
|
|
|
|
|
|
|
166
|
|
|
|
|
|
|
|
167
|
|
|
|
|
|
|
|
168
|
|
|
|
|
|
|
|
169
|
|
|
|
|
|
|
=head1 SUPPORT |
170
|
|
|
|
|
|
|
|
171
|
|
|
|
|
|
|
You can find documentation for this module with the perldoc command. |
172
|
|
|
|
|
|
|
|
173
|
|
|
|
|
|
|
perldoc Flexnet::lmutil |
174
|
|
|
|
|
|
|
|
175
|
|
|
|
|
|
|
|
176
|
|
|
|
|
|
|
You can also look for information at: |
177
|
|
|
|
|
|
|
|
178
|
|
|
|
|
|
|
=over 4 |
179
|
|
|
|
|
|
|
|
180
|
|
|
|
|
|
|
=item * RT: CPAN's request tracker (report bugs here) |
181
|
|
|
|
|
|
|
|
182
|
|
|
|
|
|
|
L |
183
|
|
|
|
|
|
|
|
184
|
|
|
|
|
|
|
=item * AnnoCPAN: Annotated CPAN documentation |
185
|
|
|
|
|
|
|
|
186
|
|
|
|
|
|
|
L |
187
|
|
|
|
|
|
|
|
188
|
|
|
|
|
|
|
=item * CPAN Ratings |
189
|
|
|
|
|
|
|
|
190
|
|
|
|
|
|
|
L |
191
|
|
|
|
|
|
|
|
192
|
|
|
|
|
|
|
=item * Search CPAN |
193
|
|
|
|
|
|
|
|
194
|
|
|
|
|
|
|
L |
195
|
|
|
|
|
|
|
|
196
|
|
|
|
|
|
|
=back |
197
|
|
|
|
|
|
|
|
198
|
|
|
|
|
|
|
|
199
|
|
|
|
|
|
|
=head1 ACKNOWLEDGEMENTS |
200
|
|
|
|
|
|
|
|
201
|
|
|
|
|
|
|
|
202
|
|
|
|
|
|
|
=head1 LICENSE AND COPYRIGHT |
203
|
|
|
|
|
|
|
|
204
|
|
|
|
|
|
|
Copyright 2015 Christopher Odenbach. |
205
|
|
|
|
|
|
|
|
206
|
|
|
|
|
|
|
This program is free software; you can redistribute it and/or modify it |
207
|
|
|
|
|
|
|
under the terms of either: the GNU General Public License as published |
208
|
|
|
|
|
|
|
by the Free Software Foundation; or the Artistic License. |
209
|
|
|
|
|
|
|
|
210
|
|
|
|
|
|
|
See http://dev.perl.org/licenses/ for more information. |
211
|
|
|
|
|
|
|
|
212
|
|
|
|
|
|
|
|
213
|
|
|
|
|
|
|
=cut |
214
|
|
|
|
|
|
|
|
215
|
|
|
|
|
|
|
sub new { |
216
|
1
|
|
|
1
|
0
|
12
|
my $pkg = shift; |
217
|
1
|
|
|
|
|
5
|
my %args = @_; |
218
|
|
|
|
|
|
|
|
219
|
1
|
|
50
|
|
|
9
|
my $lmutil = ($args{lmutil} or which ('lmutil') or ''); |
220
|
|
|
|
|
|
|
|
221
|
1
|
0
|
33
|
|
|
399
|
if (not defined $args{testfile} and not -x $lmutil ) { |
222
|
0
|
|
|
|
|
0
|
die "lmutil not executable\n"; |
223
|
|
|
|
|
|
|
} |
224
|
|
|
|
|
|
|
|
225
|
1
|
|
|
|
|
6
|
my $self = { |
226
|
|
|
|
|
|
|
lmutil => $lmutil, |
227
|
|
|
|
|
|
|
%args |
228
|
|
|
|
|
|
|
}; |
229
|
1
|
|
|
|
|
5
|
return bless ($self, $pkg); |
230
|
|
|
|
|
|
|
} |
231
|
|
|
|
|
|
|
|
232
|
|
|
|
|
|
|
sub lmstat { |
233
|
1
|
|
|
1
|
0
|
6
|
my $self = shift; |
234
|
|
|
|
|
|
|
|
235
|
1
|
|
|
|
|
4
|
my @args = @_; |
236
|
|
|
|
|
|
|
|
237
|
1
|
50
|
|
|
|
7
|
if (@args == 1) { |
238
|
1
|
|
|
|
|
3
|
push @args, 1; |
239
|
|
|
|
|
|
|
} |
240
|
1
|
|
|
|
|
3
|
my %args = @args; |
241
|
|
|
|
|
|
|
|
242
|
1
|
|
|
|
|
2
|
my ($feature, $status); |
243
|
|
|
|
|
|
|
|
244
|
1
|
|
|
|
|
7
|
my $cmd = "$self->{lmutil} lmstat"; |
245
|
|
|
|
|
|
|
|
246
|
1
|
50
|
|
|
|
5
|
if ( defined ($self->{lm_license_path})) { |
247
|
0
|
|
|
|
|
0
|
$cmd .= " -c $self->{lm_license_path}"; |
248
|
|
|
|
|
|
|
} |
249
|
|
|
|
|
|
|
|
250
|
1
|
50
|
|
|
|
4
|
if ( defined ($args{all}) ) { |
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
251
|
1
|
|
|
|
|
2
|
$cmd .= " -a"; |
252
|
|
|
|
|
|
|
} elsif ( defined ($args{feature}) ) { |
253
|
0
|
|
|
|
|
0
|
$cmd .= " -f $args{feature}"; |
254
|
|
|
|
|
|
|
} elsif ( defined ($args{daemon}) ) { |
255
|
0
|
|
|
|
|
0
|
$cmd .= " -S $args{daemon}"; |
256
|
|
|
|
|
|
|
} |
257
|
|
|
|
|
|
|
|
258
|
|
|
|
|
|
|
# for testing purpose we can provide a text file with the output of lmstat |
259
|
1
|
|
|
|
|
2
|
my $fh; |
260
|
1
|
50
|
|
|
|
4
|
if ( defined ($self->{testfile}) ) { |
261
|
1
|
50
|
|
|
|
36
|
open ($fh, $self->{testfile}) or die "Could not open $self->{testfile}: $!"; |
262
|
|
|
|
|
|
|
} else { |
263
|
0
|
0
|
|
|
|
0
|
print "Running command: $cmd\n" if $self->{verbose}; |
264
|
0
|
|
|
|
|
0
|
open ($fh, "$cmd |"); |
265
|
|
|
|
|
|
|
} |
266
|
|
|
|
|
|
|
|
267
|
1
|
|
|
|
|
23
|
while (<$fh>) { |
268
|
98
|
50
|
|
|
|
271
|
print "lmstat: $_" if $self->{verbose}; |
269
|
|
|
|
|
|
|
|
270
|
|
|
|
|
|
|
# lmgrd status |
271
|
98
|
100
|
|
|
|
1032
|
if ( my ($server, $server_status) = /^\s*([\w.-]+): license server (\S+)/ ) { |
|
|
100
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
272
|
1
|
|
|
|
|
5
|
$status->{server}->{$server}->{status} = $server_status; |
273
|
1
|
50
|
|
|
|
5
|
if ( $server_status eq "UP" ) { |
274
|
1
|
|
|
|
|
11
|
$status->{server}->{$server}->{ok} = 1; |
275
|
|
|
|
|
|
|
} else { |
276
|
0
|
|
|
|
|
0
|
$status->{server}->{$server}->{ok} = 0; |
277
|
|
|
|
|
|
|
} |
278
|
|
|
|
|
|
|
|
279
|
|
|
|
|
|
|
# vendor daemon status |
280
|
|
|
|
|
|
|
} elsif ( my ($vendor, $state) = /^\s*(\S+?): (.*)/ ) { |
281
|
3
|
|
|
|
|
11
|
$status->{vendor}->{$vendor}->{status} = $state; |
282
|
3
|
50
|
|
|
|
12
|
if ( $state =~ /^UP v([\d.]+)/ ) { |
283
|
3
|
|
|
|
|
11
|
$status->{vendor}->{$vendor}->{ok} = 1; |
284
|
3
|
|
|
|
|
23
|
$status->{vendor}->{$vendor}->{version} = $1; |
285
|
|
|
|
|
|
|
} else { |
286
|
0
|
|
|
|
|
0
|
$status->{vendor}->{$vendor}->{ok} = 0; |
287
|
|
|
|
|
|
|
} |
288
|
|
|
|
|
|
|
|
289
|
|
|
|
|
|
|
# feature usage info |
290
|
|
|
|
|
|
|
} elsif ( /^Users of (\S+):\s*\(Total of (\d+) licenses? issued;\s*Total of (\d+) lic/ ) { |
291
|
11
|
|
|
|
|
27
|
$feature = $1; |
292
|
11
|
|
|
|
|
18
|
my $issued = $2; |
293
|
11
|
|
|
|
|
19
|
my $used = $3; |
294
|
11
|
|
|
|
|
37
|
$status->{feature}->{$feature}->{issued} = $issued; |
295
|
11
|
|
|
|
|
73
|
$status->{feature}->{$feature}->{used} = $used; |
296
|
|
|
|
|
|
|
|
297
|
|
|
|
|
|
|
# user info |
298
|
|
|
|
|
|
|
} elsif ( my ($clientinfo, $version, $serverhost, $port, $handle, $rest) = |
299
|
|
|
|
|
|
|
m{^\s+(.+) \(v([\d\.]+)\) \(([^/]+)/(\d+) (\d+)\), start (.*)} ) { |
300
|
|
|
|
|
|
|
|
301
|
36
|
|
|
|
|
47
|
my ($user, $host); |
302
|
36
|
|
|
|
|
51
|
my $display = ''; |
303
|
|
|
|
|
|
|
|
304
|
|
|
|
|
|
|
# split clientinfo |
305
|
|
|
|
|
|
|
|
306
|
36
|
|
|
|
|
96
|
my @parts = split / /, $clientinfo; |
307
|
36
|
100
|
|
|
|
118
|
if (@parts == 2) { |
|
|
100
|
|
|
|
|
|
308
|
4
|
|
|
|
|
8
|
($user, $host) = @parts; |
309
|
|
|
|
|
|
|
} elsif (@parts == 3) { |
310
|
28
|
|
|
|
|
53
|
($user, $host, $display) = @parts; |
311
|
|
|
|
|
|
|
} else { |
312
|
4
|
|
|
|
|
7
|
my $max = @parts; |
313
|
|
|
|
|
|
|
|
314
|
|
|
|
|
|
|
# host = display? |
315
|
4
|
100
|
|
|
|
13
|
if ($parts[$max - 2] eq $parts[$max - 1]) { |
316
|
1
|
|
|
|
|
3
|
$display = pop @parts; |
317
|
1
|
|
|
|
|
2
|
$host = pop @parts; |
318
|
1
|
|
|
|
|
3
|
$user = join (' ', @parts); |
319
|
|
|
|
|
|
|
} else { |
320
|
|
|
|
|
|
|
# display contains / or : ? |
321
|
3
|
|
|
|
|
4
|
my $i = 2; |
322
|
3
|
|
|
|
|
8
|
while ($i <= @parts) { |
323
|
3
|
50
|
|
|
|
13
|
if ($parts[$i] =~ m{^[:/]}) { |
324
|
3
|
|
|
|
|
5
|
$display = $parts[$i]; |
325
|
3
|
|
|
|
|
5
|
$host = $parts[$i - 1]; |
326
|
3
|
|
|
|
|
7
|
$user = join (' ', map { $parts[$_] } 0..$i-2); |
|
3
|
|
|
|
|
10
|
|
327
|
3
|
|
|
|
|
22
|
last; |
328
|
|
|
|
|
|
|
} |
329
|
0
|
|
|
|
|
0
|
$i++; |
330
|
|
|
|
|
|
|
} |
331
|
|
|
|
|
|
|
|
332
|
|
|
|
|
|
|
# if still no luck, just guess |
333
|
3
|
50
|
|
|
|
11
|
unless (defined $user) { |
334
|
0
|
|
|
|
|
0
|
($user, $host, $display) = @parts; |
335
|
|
|
|
|
|
|
} |
336
|
|
|
|
|
|
|
} |
337
|
|
|
|
|
|
|
} |
338
|
|
|
|
|
|
|
|
339
|
|
|
|
|
|
|
# starttime and optional number of licenses |
340
|
36
|
|
|
|
|
55
|
my $startdate; |
341
|
36
|
|
|
|
|
45
|
my $licenses = 1; |
342
|
36
|
100
|
|
|
|
73
|
if ($rest =~ /^([^,]+), (\d+) license/) { |
343
|
1
|
|
|
|
|
4
|
$startdate = $1; |
344
|
1
|
|
|
|
|
2
|
$licenses = $2; |
345
|
|
|
|
|
|
|
} else { |
346
|
35
|
|
|
|
|
59
|
$startdate = $rest; |
347
|
|
|
|
|
|
|
} |
348
|
|
|
|
|
|
|
|
349
|
36
|
|
|
|
|
44
|
push @{$status->{feature}->{$feature}->{users}}, { |
|
36
|
|
|
|
|
483
|
|
350
|
|
|
|
|
|
|
user=>$user, |
351
|
|
|
|
|
|
|
host=>$host, |
352
|
|
|
|
|
|
|
display=>$display, |
353
|
|
|
|
|
|
|
licenses=>$licenses, |
354
|
|
|
|
|
|
|
serverhost=>$serverhost, |
355
|
|
|
|
|
|
|
port=>$port, |
356
|
|
|
|
|
|
|
handle=>$handle, |
357
|
|
|
|
|
|
|
startdate=>$startdate |
358
|
|
|
|
|
|
|
}; |
359
|
|
|
|
|
|
|
|
360
|
|
|
|
|
|
|
# reservation info |
361
|
|
|
|
|
|
|
} elsif ( my ($reservations, $type, $group) = /^\s+(\d+)\s+RESERVATIONs? for ([\w_]+) ([\w_-]+) / ) { |
362
|
4
|
|
|
|
|
5
|
push @{$status->{feature}->{$feature}->{reservations}}, |
|
4
|
|
|
|
|
40
|
|
363
|
|
|
|
|
|
|
{type=>$type, group=>$group, reservations=>$reservations}; |
364
|
|
|
|
|
|
|
} |
365
|
|
|
|
|
|
|
|
366
|
|
|
|
|
|
|
} |
367
|
1
|
|
|
|
|
8
|
close ($fh); |
368
|
|
|
|
|
|
|
|
369
|
1
|
|
|
|
|
7
|
return $status; |
370
|
|
|
|
|
|
|
} |
371
|
|
|
|
|
|
|
|
372
|
|
|
|
|
|
|
sub lmremove { |
373
|
0
|
|
|
0
|
0
|
|
my $self = shift; |
374
|
0
|
|
|
|
|
|
my %args = @_; |
375
|
0
|
|
|
|
|
|
my $cmd; |
376
|
|
|
|
|
|
|
|
377
|
0
|
|
|
|
|
|
foreach my $arg (qw (feature serverhost port handle)) { |
378
|
0
|
0
|
|
|
|
|
die "Parameter '$arg' missing\n" unless $args{$arg}; |
379
|
|
|
|
|
|
|
} |
380
|
|
|
|
|
|
|
|
381
|
0
|
|
|
|
|
|
$cmd = "$self->{lmutil} lmremove"; |
382
|
0
|
0
|
|
|
|
|
if ( defined ($self->{lm_license_path})) { |
383
|
0
|
|
|
|
|
|
$cmd .= " -c $self->{lm_license_path}"; |
384
|
|
|
|
|
|
|
} |
385
|
0
|
|
|
|
|
|
$cmd .= " -h $args{feature} $args{serverhost} $args{port} $args{handle}"; |
386
|
|
|
|
|
|
|
|
387
|
0
|
0
|
|
|
|
|
print "Running command: $cmd\n" if $self->{verbose}; |
388
|
0
|
|
|
|
|
|
system($cmd); |
389
|
|
|
|
|
|
|
} |
390
|
|
|
|
|
|
|
|
391
|
|
|
|
|
|
|
|
392
|
|
|
|
|
|
|
|
393
|
|
|
|
|
|
|
|
394
|
|
|
|
|
|
|
1; # End of Flexnet::lmutil |