~ubuntu-branches/ubuntu/trusty/net-snmp/trusty

« back to all changes in this revision

Viewing changes to perl/manager/manager.pm

  • Committer: Bazaar Package Importer
  • Author(s): Martin Pitt
  • Date: 2004-09-13 12:06:21 UTC
  • Revision ID: james.westby@ubuntu.com-20040913120621-g952ntonlleihcvm
Tags: upstream-5.1.1
ImportĀ upstreamĀ versionĀ 5.1.1

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#!/usr/local/bin/perl
 
2
 
 
3
package NetSNMP::manager;
 
4
 
 
5
use strict ();
 
6
use Apache::Constants qw(:common);
 
7
use CGI qw(:standard delete_all);
 
8
use SNMP ();
 
9
use DBI ();
 
10
use NetSNMP::manager::displaytable qw(displaytable displaygraph);
 
11
 
 
12
# globals
 
13
$NetSNMP::manager::hostname = 'localhost';          # Host that serves the mSQL Database
 
14
$NetSNMP::manager::dbname = 'snmp';                 # mySQL Database name
 
15
$NetSNMP::manager::user = 'root';
 
16
# $NetSNMP::manager::pass = "password";
 
17
$NetSNMP::manager::imagebase = "/home/hardaker/src/snmp/manager";       # <=== CHANGE ME ====
 
18
$NetSNMP::manager::redimage = "/graphics/red.gif";
 
19
$NetSNMP::manager::greenimage = "/graphics/green.gif";
 
20
#$NetSNMP::manager::verbose = 1;
 
21
$NetSNMP::manager::tableparms  = "border=1 bgcolor=\"#c0c0e0\"";
 
22
$NetSNMP::manager::headerparms = "border=1 bgcolor=\"#b0e0b0\"";
 
23
 
 
24
# init the snmp library
 
25
$SNMP::save_descriptions=1;
 
26
#SNMP::init_mib();
 
27
 
 
28
%NetSNMP::manager::myorder = qw(id 0 oidindex 1 host 2 updated 3);
 
29
 
 
30
sub handler {
 
31
    my $r = shift;
 
32
    Apache->request($r);
 
33
 
 
34
    # get info from handler
 
35
    my $hostname = $r->dir_config('hostname') || $NetSNMP::manager::hostname;
 
36
    my $dbname = $r->dir_config('dbname') || $NetSNMP::manager::dbname;
 
37
    my $sqluser = $r->dir_config('user') || $NetSNMP::manager::user;
 
38
    my $pass = $r->dir_config('pass') || $NetSNMP::manager::pass;
 
39
    my $verbose = $r->dir_config('verbose') || $NetSNMP::manager::verbose;
 
40
 
 
41
#===========================================================================
 
42
#  Global defines
 
43
#===========================================================================
 
44
 
 
45
my ($dbh, $query, $remuser);
 
46
 
 
47
$remuser = $ENV{'REMOTE_USER'};
 
48
$remuser = "guest" if (!defined($remuser) || $remuser eq "");
 
49
 
 
50
#===========================================================================
 
51
# Connect to the mSQL database with the appropriate driver
 
52
#===========================================================================
 
53
($dbh = DBI->connect("DBI:mysql:database=$dbname;host=$hostname", $sqluser, $pass))
 
54
    or die "\tConnect not ok: $DBI::errstr\n";
 
55
 
 
56
#===========================================================================
 
57
# stats Images, for inclusion on another page. (ie, slashdot user box)
 
58
#===========================================================================
 
59
if (my $group = param('groupstat')) {
 
60
    $r->content_type("image/gif");
 
61
    $r->send_http_header();
 
62
    my $cur = getcursor($dbh, "select host from usergroups as ug, hostgroups as hg where ug.groupname = '$group' and hg.groupname = '$group' and user = '$remuser'");
 
63
    while (my $row = $cur->fetchrow_hashref ) {
 
64
        if (checkhost($dbh, $group, $row->{'host'})) {
 
65
            open(I, "$NetSNMP::manager::imagebase$NetSNMP::manager::redimage");
 
66
            while(read(I, $_, 4096)) { print; }
 
67
            close(I);
 
68
        }
 
69
    }
 
70
    open(I, "$NetSNMP::manager::imagebase$NetSNMP::manager::greenimage");
 
71
    while(read(I, $_, 4096)) { print; }
 
72
    close(I);
 
73
    return OK();
 
74
}
 
75
 
 
76
 
 
77
sub date_format {
 
78
    my $time = shift;
 
79
    my @out = localtime($time);
 
80
    my $ret = $out[4] . "-" . $out[3] . "-" . $out[5] . " " . $out[2] . " " . $out[1];
 
81
#    print STDERR "$time: $ret\n";
 
82
    return $ret;
 
83
}
 
84
 
 
85
 
 
86
#
 
87
# Graphing of historical data
 
88
#
 
89
if ((param('displaygraph') || param('dograph')) && param('table')) {
 
90
    my $host = param('host');
 
91
    my $group = param('group');
 
92
    if (!isuser($dbh, $remuser, $group)) {
 
93
        $r->content_type("image/png");
 
94
        $r->send_http_header();
 
95
        print "Unauthorized access to that group ($group)\n";
 
96
        return Exit($dbh, $group);
 
97
    }    
 
98
    my $table = param('table');
 
99
    my @columns;
 
100
 
 
101
    if (!param('dograph')) {
 
102
        $r->content_type("text/html");
 
103
        $r->send_http_header();
 
104
        print "<body bgcolor=\"#ffffff\">\n";
 
105
        print "<form>\n";
 
106
        print "<table border=1><tr><td>\n";
 
107
 
 
108
        print "<table>\n";
 
109
        print "<tr align=top><th></th><th>Select indexes<br>to graph</th></tr>\n";
 
110
 
 
111
        my $handle = getcursor($dbh, "SELECT sql_small_result distinct(oidindex) FROM $table where host = '$host'");
 
112
        my @cols;
 
113
        while (  $row = $handle->fetchrow_hashref ) {
 
114
            print "<tr><td>$row->{oidindex}</td><td><input type=checkbox value=1 name=" . 'graph_' . displaytable::to_unique_key($row->{'oidindex'}) . "></td></tr>\n";
 
115
        }
 
116
        print "</table>\n";
 
117
 
 
118
        print "</td><td>\n";
 
119
 
 
120
        print "<table>\n";
 
121
        print "<tr align=top><th></th><th>Select Columns<br>to graph</th></tr>\n";
 
122
        my $handle = getcursor($dbh, "SELECT * FROM $table limit 1");
 
123
        my $row = $handle->fetchrow_hashref;
 
124
        map { print "<tr><td>$_</td><td><input type=checkbox value=1 name=column_" . displaytable::to_unique_key($_) . "></td></tr>\n"; } keys(%$row);
 
125
        print "</table>\n";
 
126
 
 
127
        print "</td></tr></table>\n";
 
128
 
 
129
        print "<br>Graph as a Rate: <input type=checkbox value=1 name=graph_as_rate><br>\n";
 
130
        print "<br>Maximum Y Value: <input type=text value=inf name=max_y><br>\n";
 
131
        print "<br>Minimum Y Value: <input type=text value=-inf name=min_y><br>\n";
 
132
 
 
133
        print "<input type=hidden name=table value=\"$table\">\n";
 
134
        print "<input type=hidden name=host value=\"$host\">\n";
 
135
        print "<input type=hidden name=dograph value=1>\n";
 
136
        print "<input type=hidden name=group value=\"$group\">\n";
 
137
        print "<input type=submit name=\"Make Graph\">\n";
 
138
 
 
139
        print "</form>\n";
 
140
 
 
141
        my $handle = getcursor($dbh, "SELECT distinct(oidindex) FROM $table where host = '$host' order by oidindex");
 
142
        return Exit($dbh, $group);
 
143
    }
 
144
    if (param('graph_all_data')) {
 
145
        $clause = "host = '$host'";
 
146
    } else {
 
147
        my $handle = getcursor($dbh, "SELECT distinct(oidindex) FROM $table where host = '$host'");
 
148
        $clause = "where (";
 
149
        while (  $row = $handle->fetchrow_hashref ) {
 
150
#           print STDERR "graph test: " . $row->{'oidindex'} . "=" . "graph_" . displaytable::to_unique_key($row->{'oidindex'}) . "=" . param("graph_" . displaytable::to_unique_key($row->{'oidindex'})) . "\n";
 
151
            if (param("graph_" . displaytable::to_unique_key($row->{'oidindex'}))) {
 
152
                $clause .= " or oidindex = " . $row->{'oidindex'} . "";
 
153
            }
 
154
        }
 
155
 
 
156
        my $handle = getcursor($dbh, "SELECT * FROM $table limit 1");
 
157
        my $row = $handle->fetchrow_hashref;
 
158
        map { push @columns, $_ if (param('column_' . displaytable::to_unique_key($_))) } keys(%$row);
 
159
 
 
160
        $clause .= ")";
 
161
        $clause =~ s/\( or /\(/;
 
162
        if ($clause =~ /\(\)/ || $#columns == -1) {
 
163
            $r->content_type("text/html");
 
164
            $r->send_http_header();
 
165
            print "<body bgcolor=\"#ffffff\">\n";
 
166
            print "<h1>No Data to Graph</h1>\n";
 
167
            print STDERR "No data to graph: $clause, $#columns\n";
 
168
            return Exit($dbh, "$group");
 
169
        }
 
170
        $clause .= " and host = '$host'";
 
171
    }
 
172
 
 
173
#    print STDERR "graphing clause: $clause\n";
 
174
 
 
175
    # all is ok, display the graph
 
176
 
 
177
    $r->content_type("image/png");
 
178
    $r->send_http_header();
 
179
 
 
180
    print STDERR "graphing clause: $clause, columns: ", join(", ",@columns), "\n";
 
181
    my @args;
 
182
    push (@args, '-rate', '60') if (param('graph_as_rate'));
 
183
    push (@args, '-max', param('max_y')) if (param('max_y') && param('max_y') =~ /^[-.\d]+$/);
 
184
    push (@args, '-min', param('min_y')) if (param('min_y') && param('min_y') =~ /^[-.\d]+$/);
 
185
 
 
186
    my $ret = 
 
187
    displaygraph($dbh, $table,
 
188
#                '-xcol', "date_format(updated,'%m-%d-%y %h:%i')",
 
189
                 '-xcol', "unix_timestamp(updated)",
 
190
                 '-pngparms', [
 
191
                     'x_labels_vertical', '1',
 
192
                     'x_tick_number', 6,
 
193
                     'x_number_format', \&date_format,
 
194
                     'y_label', 'Count/Min',
 
195
                     'title', $table,
 
196
#                    'y_min_value', 0,
 
197
                 ],
 
198
                 '-clauses', "$clause order by updated",
 
199
                 @args,
 
200
                 '-columns', \@columns,
 
201
                 '-indexes', ['oidindex']);
 
202
    print STDERR "$ret rows graphed\n";
 
203
    return OK();
 
204
}
 
205
 
 
206
#===========================================================================
 
207
# Start HTML.
 
208
#===========================================================================
 
209
$r->content_type("text/html");
 
210
$r->send_http_header();
 
211
print "<body bgcolor=\"#ffffff\">\n";
 
212
print "<h1>UCD-SNMP Management Console</h1>\n";
 
213
print "<hr>\n";
 
214
 
 
215
#===========================================================================
 
216
# Display mib related data information
 
217
#===========================================================================
 
218
if (param('displayinfo')) {
 
219
    makemibtable(param('displayinfo'));
 
220
    return Exit($dbh, "");
 
221
}
 
222
 
 
223
#===========================================================================
 
224
# Display a generic sql table of any kind (debugging).
 
225
#===========================================================================
 
226
# if (my $disptable = param('displaytable')) {
 
227
#     if (param('editable') == 1) {
 
228
#       print "<form submit=dont>\n";
 
229
#       displaytable($disptable, -editable, 1);
 
230
#       print "</form>\n";
 
231
#     } else {
 
232
#       displaytable($disptable);
 
233
#     }
 
234
#     return Exit($dbh,  "");
 
235
# }
 
236
 
 
237
#===========================================================================
 
238
# Get host and group from CGI query.
 
239
#===========================================================================
 
240
my $host = param('host');
 
241
my $group = param('group');
 
242
 
 
243
#===========================================================================
 
244
# Editable user information
 
245
#===========================================================================
 
246
 
 
247
if (param('setuponcall')) {
 
248
    print "<title>oncall schedule for user: $remuser</title>\n";
 
249
    print "<h2>oncall schedule for user: $remuser</h2>\n";
 
250
    print "<p>Please select your oncall schedule and mailing addresses for your groups below:";
 
251
    if (!isexpert($remuser)) {
 
252
        print "<ul>\n";
 
253
        print "<li>Values for the days/hours fields can be comma seperated lists of hours/days/ranges.  EG: hours: 7-18,0-4.\n";
 
254
        print "</ul>\n";
 
255
    }
 
256
    print "<form method=post><input type=hidden name=setuponcall value=1>\n";
 
257
    displaytable($dbh, 'oncall',
 
258
    '-clauses',"where user = '$remuser' order by groupname",
 
259
    '-select','id, user, groupname, email, pager, days, hours',
 
260
    '-selectorder', 1,
 
261
    '-notitle', 1,
 
262
    '-editable', 1,
 
263
    '-indexes', ['id','user','groupname'],
 
264
    '-CGI', $CGI::Q
 
265
    );
 
266
    print "<input type=submit value=\"submit changes\">\n";
 
267
    print "</form>\n";
 
268
    return Exit($dbh, $group);
 
269
}
 
270
 
 
271
#===========================================================================
 
272
# show the list of groups a user belongs to.
 
273
#===========================================================================
 
274
if (!defined($group)) {
 
275
    my @groups = getgroupsforuser($dbh, $remuser);
 
276
    print "<title>Net-SNMP Group List</title>\n";
 
277
    print "<h2>Host groupings you may access:</h2>\n";
 
278
    if (!isexpert($remuser)) {
 
279
        print "<ul>\n";
 
280
        print "<li>Click on a group to operate or view the hosts in that group.\n";
 
281
        print "<li>Click on a red status light below to list the problems found.\n";
 
282
        print "</ul>\n";
 
283
    }
 
284
        
 
285
    if ($#groups > 0) {
 
286
        displaytable($dbh, 'usergroups', 
 
287
                     '-clauses', "where (user = '$remuser')",
 
288
                     '-select', 'distinct groupname',
 
289
                     '-notitle', 1,
 
290
                     '-printonly', ['groupname'],
 
291
                     '-datalink', sub { my $q = self_url();
 
292
                                        my $key = shift;
 
293
                                        my $h = shift;
 
294
                                        return if ($key ne "groupname");
 
295
                                        return addtoken($q,"group=$h");
 
296
                                    },
 
297
                     '-beginhook', 
 
298
                     sub { 
 
299
                         my $q = self_url();
 
300
                         my($dbh, $junk, $data) = @_;
 
301
                         if (!defined($data)) {
 
302
                             print "<th>Status</th>";
 
303
                             return;
 
304
                         }
 
305
                         my ($cur, $row);
 
306
                         $cur = getcursor($dbh, "select host from hostgroups where groupname = '$data->{groupname}'");
 
307
                         while (  $row = $cur->fetchrow_hashref ) {
 
308
                             if (checkhost($dbh, $data->{'groupname'}, 
 
309
                                           $row->{'host'})) {
 
310
                                 print "<td><a href=\"" . addtoken($q,"group=$data->{groupname}&summarizegroup=1") . "\"><img border=0 src=$NetSNMP::manager::redimage></a></td>\n";
 
311
                                 return;
 
312
                             }
 
313
                         }
 
314
                         print "<td><img src=$NetSNMP::manager::greenimage></td>\n";
 
315
                     }
 
316
                     );
 
317
        $dbh->disconnect();
 
318
        return Exit($dbh,  $group);
 
319
    } else {
 
320
        if ($#groups == -1) {
 
321
            print "You are not configured to use the Net-SNMP-manager, please contact your system administrator.";
 
322
            return Exit($dbh,  $group);
 
323
        }
 
324
        $group = $groups[0];
 
325
    }
 
326
}
 
327
 
 
328
#===========================================================================
 
329
# reject un-authorized people accessing a certain group
 
330
#===========================================================================
 
331
if (!isuser($dbh, $remuser, $group)) {
 
332
    print "Unauthorized access to that group ($group)\n";
 
333
    return Exit($dbh, $group);
 
334
}    
 
335
 
 
336
#===========================================================================
 
337
# add a new host to a group
 
338
#===========================================================================
 
339
if (defined(my $newhost = param('newhost'))) {
 
340
    if (isadmin($dbh, $remuser, $group)) {
 
341
        if ($dbh->do("select * from hostgroups where host = '$newhost' and groupname = '$group'") eq "0E0") {
 
342
            $dbh->do("insert into hostgroups(host,groupname) values('$newhost','$group')") ;
 
343
        } else {
 
344
            print "<b>ERROR: host $newhost already in $group</b>\n";
 
345
        }
 
346
        CGI::delete('newhost');
 
347
    }
 
348
}
 
349
 
 
350
#===========================================================================
 
351
# display setup configuration for a group
 
352
#===========================================================================
 
353
if (defined(param('setupgroup'))) {
 
354
    if (isadmin($dbh, $remuser, $group)) {
 
355
        setupgroup($dbh, $group);
 
356
    } else {
 
357
        print "<h2>You're not able to perform setup operations for group $group\n";
 
358
    }
 
359
    return Exit($dbh, $group);
 
360
}
 
361
 
 
362
#===========================================================================
 
363
# save configuration information submitted about a group
 
364
#===========================================================================
 
365
if (defined(param('setupgroupsubmit')) && 
 
366
    isadmin($dbh, $remuser, $group)) {
 
367
    setupgroupsubmit($dbh, $group);
 
368
    delete_all();
 
369
    param(-name => 'group', -value => $group);
 
370
    print "<a href=\"" . self_url() . "\">Entries submitted</a>";
 
371
    return Exit($dbh, $group);
 
372
}
 
373
 
 
374
#===========================================================================
 
375
# user preferences
 
376
#===========================================================================
 
377
if (defined(param('userprefs'))) {
 
378
    setupuserpreferences($dbh, $remuser, $group);
 
379
    return Exit($dbh, $group);
 
380
}
 
381
 
 
382
#===========================================================================
 
383
# save submitted user preferences
 
384
#===========================================================================
 
385
if (defined(param('setupuserprefssubmit')) && 
 
386
    isadmin($dbh, $remuser, $group)) {
 
387
    setupusersubmit($dbh, $remuser, $group);
 
388
    delete_all();
 
389
    param(-name => 'group', -value => $group);
 
390
    print "<a href=\"" . self_url() . "\">Entries submitted</a>";
 
391
    return Exit($dbh, $group);
 
392
}
 
393
 
 
394
#===========================================================================
 
395
# summarize problems in a group
 
396
#===========================================================================
 
397
if (defined(param('summarizegroup'))) {
 
398
    print "<title>group problem summary: $group</title>\n";
 
399
    print "<h2>The following is a list of problems in the group \"$group\":</h2>\n";
 
400
    summarizeerrors($dbh, "where groupname = '$group'");
 
401
    return Exit($dbh, $group);
 
402
}
 
403
 
 
404
#===========================================================================
 
405
# summarize problems on a host
 
406
#===========================================================================
 
407
if (defined($host) && defined(param('summarizehost'))) {
 
408
    print "<title>host summary: $host</title>\n";
 
409
    print "<h2>The following is a list of problems for the host \"$host\":</h2>\n";
 
410
    summarizeerrors($dbh, "where groupname = '$group' and host = '$host'");
 
411
    return Exit($dbh, $group);
 
412
}
 
413
 
 
414
#===========================================================================
 
415
# display a list of hosts in a group
 
416
#===========================================================================
 
417
if (!defined($host)) {
 
418
    print "<title>Net-SNMP Host $host</title>\n";
 
419
    print "<h2>Hosts in the group \"$group\":</h2>\n";
 
420
    if (!isexpert($remuser)) {
 
421
        print "<ul>\n";
 
422
        if (isadmin($dbh, $remuser, $group)) {
 
423
            my $q = self_url();
 
424
            $q =~ s/\?.*//;
 
425
            print "<li>Make sure you <a href=\"" . addtoken($q,"group=$group&setupgroup=1") . "\">set up the host</a> for the SNMP tables you want to monitor.\n";
 
426
        }
 
427
        print "<li>Click on a hostname to operate on or view the information tables associated with that group.\n";
 
428
        print "<li>Click on a red status light below to list the problems found in with a particular host.\n";
 
429
        print "</ul>\n";
 
430
    }
 
431
    displaytable($dbh, 'hostgroups', 
 
432
                 '-notitle',0,
 
433
                 '-clauses', "where (groupname = '$group')",
 
434
                 '-select', 'distinct host, sysObjectId, sysDescr, sysUpTime, versionTag',
 
435
                 '-datalink', sub { my $q = self_url();
 
436
                                    my $key = shift;
 
437
                                    my $h = shift;
 
438
                                    return if ($key ne "host");
 
439
                                    return addtoken($q,"host=$h");
 
440
                                },
 
441
                 '-beginhook', 
 
442
                 sub { 
 
443
                     my $q = self_url();
 
444
                     my($dbh, $junk, $data) = @_;
 
445
                     if (!defined($data)) {
 
446
                         print "<th>Status</th>";
 
447
                         return;
 
448
                     }
 
449
                     if (checkhost($dbh, $group, $data->{'host'})) {
 
450
                         print "<td><a href=\"" . addtoken($q,"group=$group&summarizehost=1&host=$data->{host}") . "\"><img border=0 src=$NetSNMP::manager::redimage></a></td>\n";
 
451
                     } else {
 
452
                         print "<td><img src=$NetSNMP::manager::greenimage></td>\n";
 
453
                     }
 
454
                 }
 
455
                 );
 
456
    if (isadmin($dbh, $remuser, $group)) {
 
457
        addhostentryform($group);
 
458
        my $q = self_url();
 
459
        $q =~ s/\?.*//;
 
460
        print "<a href=\"" . addtoken($q,"group=$group&setupgroup=1") . "\">setup group $group</a>\n";
 
461
    }
 
462
    return Exit($dbh, $group);
 
463
}
 
464
 
 
465
#===========================================================================
 
466
# setup the host's history records
 
467
#===========================================================================
 
468
if (param('setuphost')) {
 
469
    print "<title>Net-SNMP history setup for host: $host</title>\n";
 
470
    print "<h2>Net-SNMP history setup for the host: \"$host\"</h2>\n";
 
471
    print "<p>Enter the number of days to keep the data for a given table for the host \"$host\":\n";
 
472
    if (!isexpert($remuser)) {
 
473
        print "<ul>\n";
 
474
        print "<li>Numbers must be greater than or equal to 1 to enable history logging.\n";
 
475
        print "</ul>\n";
 
476
    }
 
477
    print "<form method=post><input type=hidden name=setuphost value=1><input type=hidden name=host value=\"$host\"><input type=hidden name=group value=\"$group\">\n";
 
478
    displaytable($dbh, 'hosttables',
 
479
    '-clauses',"where host = '$host' and groupname = '$group'",
 
480
    '-select','groupname, host, tablename, keephistory',
 
481
    '-selectorder', 1,
 
482
    '-notitle', 1,
 
483
    '-editable', 1,
 
484
    '-indexes', ['groupname','host','tablename'],
 
485
    '-CGI', $CGI::Q
 
486
    );
 
487
    print "<input type=submit value=\"submit changes\">\n";
 
488
    print "</form>\n";
 
489
    return Exit($dbh, $group);
 
490
}
 
491
 
 
492
#===========================================================================
 
493
# display a huge table of history about something
 
494
#===========================================================================
 
495
if (param('displayhistory')) {
 
496
    if (!isuser($dbh, $remuser, $group)) {
 
497
        print "Unauthorized access to that group ($group)\n";
 
498
        return Exit($dbh, $group);
 
499
    }
 
500
    displaytable($dbh, param('table'), 
 
501
    '-clauses', "where (host = '$host')",
 
502
    '-dolink', \&linktodisplayinfo,
 
503
    '-dontdisplaycol', "select * from userprefs where user = '$remuser' and groupname = '$group' and tablename = ? and columnname = ? and displayit = 'N'"
 
504
    );
 
505
    return Exit($dbh, $group);
 
506
}
 
507
 
 
508
#===========================================================================
 
509
# display inforamation about a host
 
510
#  optionally add new collection tables
 
511
#===========================================================================
 
512
showhost($dbh, $host, $group, $remuser);
 
513
if (isadmin($dbh, $remuser, $group)) {
 
514
    if (param('newtables')) {
 
515
        my $x = param('newtables');
 
516
        $x =~ s/,/ /g;
 
517
        if (/[^\w\s]/) {
 
518
            print "<br>Illegal table names in addition list: $x<br>\n" 
 
519
        } else {
 
520
            my @x = split(/\s+/,$x);
 
521
            foreach my $i (@x) {
 
522
                $dbh->do("insert into hosttables(host, groupname, tablename, keephistory) values('$host','$group','$i','0')");
 
523
            }
 
524
            print "<br>adding: ",join(", ",@x),"<br>\n";
 
525
        }
 
526
    } else {
 
527
        print "<br>Add new MIB Tables or Groups that you want to collect for this host: <form><input type=hidden name=host value=\"$host\"><input type=hidden name=group value=\"$group\"><input name=\"newtables\" type=text><br><input type=submit value=\"add tables\"></form>\n";
 
528
    }
 
529
    my $q = self_url();
 
530
    $q =~ s/\?.*//;
 
531
    print "<a href=\"" . addtoken($q, "setuphost=1&host=$host&group=$group") . "\">setup host $host</a>\n";
 
532
}
 
533
return Exit($dbh, $group);
 
534
 
 
535
#===========================================================================
 
536
# END of handler
 
537
#===========================================================================
 
538
 
 
539
}
 
540
 
 
541
# add a token to a url string.  Use either a ? or an & depending on
 
542
# existence of ?.
 
543
sub addtoken {
 
544
    my $url = shift;
 
545
    my $token = shift;
 
546
    return "$url&$token" if ($url =~ /\?/);
 
547
    return "$url?$token";
 
548
}
 
549
 
 
550
#
 
551
# summarizeerrors(DB-HANDLE, CLAUSE):
 
552
#   summarize the list of errors in a given CLAUSE
 
553
#
 
554
sub summarizeerrors {
 
555
    my $dbh = shift;
 
556
    my $clause = shift;
 
557
    $clause = "where" if ($clause eq "");
 
558
    my $clause2 = $clause;
 
559
    $clause2 =~ s/ host / hosterrors.host /;
 
560
 
 
561
    # Major errors
 
562
    displaytable($dbh, 'hosterrors, hostgroups',  # , hostgroups
 
563
                 '-select', "hosterrors.host as host, errormsg",
 
564
                 '-notitle', 1,
 
565
                 '-title', "Fatal Errors",
 
566
                 '-clauses', "$clause2 and hosterrors.host = hostgroups.host",
 
567
                 '-beginhook', sub {
 
568
                     if ($#_ < 2) {
 
569
                         #doing header;
 
570
                         print "<td></td>";
 
571
                     } else {
 
572
                         print "<td><img src=\"$NetSNMP::manager::redimage\"></td>\n";
 
573
                     }});
 
574
 
 
575
    my $tabletop = "<br><table $NetSNMP::manager::tableparms><tr $NetSNMP::manager::headerparms><th><b>Host</b></th><th><b>Table</b></th><th><b>Description</b></th></tr>\n";
 
576
    my $donetop = 0;
 
577
    my $cursor = 
 
578
        getcursor($dbh, "SELECT * FROM hosttables $clause");
 
579
 
 
580
    while (my $row = $cursor->fetchrow_hashref ) {
 
581
 
 
582
        my $exprs = getcursor($dbh, "SELECT * FROM errorexpressions where (tablename = '$row->{tablename}')");
 
583
        
 
584
        while (my  $expr = $exprs->fetchrow_hashref ) {
 
585
            my $errors = getcursor($dbh, "select * from $row->{tablename} where $expr->{expression} and host = '$row->{host}'");
 
586
            while (my  $error = $errors->fetchrow_hashref ) {
 
587
                print $tabletop if ($donetop++ == 0);
 
588
                print "<tr><td>$row->{host}</td><td>$row->{tablename}</td><td>$expr->{returnfield}: $error->{$expr->{returnfield}}</td></tr>";
 
589
            }
 
590
        }
 
591
    }
 
592
    print "</table>";
 
593
}
 
594
 
 
595
#
 
596
# getcursor(CMD):
 
597
#    genericlly get a cursor for a given sql command, displaying and
 
598
#    printing errors where necessary.
 
599
#
 
600
sub getcursor {
 
601
    my $dbh = shift;
 
602
    my $cmd = shift;
 
603
    my $cursor;
 
604
    ( $cursor = $dbh->prepare( $cmd ))
 
605
        or print "\nnot ok: $DBI::errstr\n";
 
606
    ( $cursor->execute )
 
607
        or print( "\tnot ok: $DBI::errstr\n" );
 
608
    return $cursor;
 
609
}
 
610
 
 
611
#
 
612
# mykeysort($a, $b)
 
613
#    sorts $a and $b against the order in the mib or against the hard
 
614
#    coded special list.
 
615
#
 
616
sub mykeysort {
 
617
    my $a = $displaytable::a;
 
618
    my $b = $displaytable::b;
 
619
    my $mb = $SNMP::MIB{SNMP::translateObj($b)};
 
620
    my $ma = $SNMP::MIB{SNMP::translateObj($a)};
 
621
 
 
622
    return $NetSNMP::manager::myorder{$a} <=> $NetSNMP::manager::myorder{$b} if ((defined($NetSNMP::manager::myorder{$a}) || !defined($ma->{'subID'})) && (defined($NetSNMP::manager::myorder{$b}) || !defined($mb->{'subID'})));
 
623
    return 1 if (defined($NetSNMP::manager::myorder{$b}) || !defined($mb->{'subID'}));
 
624
    return -1 if (defined($NetSNMP::manager::myorder{$a}) || !defined($ma->{'subID'}));
 
625
 
 
626
    $ma->{'subID'} <=> $mb->{'subID'};
 
627
}
 
628
 
 
629
#
 
630
# checkhost(GROUP, HOST):
 
631
#    if anything in a host is an error, as defined by the
 
632
#    errorexpressions table, return 1, else 0
 
633
#
 
634
sub checkhost {
 
635
    my $dbh = shift;
 
636
    my $group = shift;
 
637
    my $host = shift;
 
638
    my ($tblh);
 
639
 
 
640
    return 2 if ($dbh->do("select * from hosterrors where host = '$host'") ne "0E0");
 
641
 
 
642
    # get a list of tables we want to display
 
643
    $tblh = getcursor($dbh, "SELECT * FROM hosttables where (host = '$host' and groupname = '$group')");
 
644
 
 
645
    # table data
 
646
    my($exprs, $tablelist);
 
647
    while ( $tablelist = $tblh->fetchrow_hashref ) {
 
648
        $exprs = getcursor($dbh, "SELECT * FROM errorexpressions where (tablename = '$tablelist->{tablename}')");
 
649
        while(my $expr = $exprs->fetchrow_hashref) {
 
650
            if ($dbh->do("select * from $tablelist->{tablename} where $expr->{expression} and host = '$host'") ne "0E0") {
 
651
                return 1;
 
652
            }
 
653
        }
 
654
    }
 
655
    return 0;
 
656
}
 
657
 
 
658
#
 
659
#  showhost(HOST):
 
660
#
 
661
#    display all the tables monitored for a given host (in a group).
 
662
#
 
663
sub showhost {
 
664
    my $dbh = shift;
 
665
    my $host = shift;
 
666
    my $group = shift;
 
667
    my $remuser = shift;
 
668
    my $q = self_url();
 
669
    $q =~ s/\?.*//;
 
670
    # host header
 
671
    print "<title>Net-SNMP manager report for host: $host</title>\n";
 
672
    print "<h2>Monitored information for the host $host</h2>\n";
 
673
    if (!isexpert($remuser)) {
 
674
        print "<ul>\n";
 
675
        print "<li>Click on a column name for information about the data in that column.\n";
 
676
        print "<li>Click on a column name or table name for information about the data in the table.\n";
 
677
        print "<li>If you are <a href=\"" . addtoken($q, "setuphost=1&host=$host&group=$group") . "\">collecting past history</a> for a data set, links will appear below the table that allow you to view and/or graph the historic data.\n";
 
678
        print "</ul>\n";
 
679
    }
 
680
 
 
681
    # does the host have a serious error?
 
682
 
 
683
    my $errlist = getcursor($dbh, "SELECT * FROM hosterrors where (host = '$host')");
 
684
    if ( $dbh->do("SELECT * FROM hosterrors where (host = '$host')") ne "0E0") {
 
685
        displaytable($dbh, 'hosterrors', 
 
686
                     '-clauses', "where (host = '$host')",
 
687
                     '-dontdisplaycol', "select * from userprefs where user = '$remuser' and groupname = '$group' and tablename = ? and columnname = ? and displayit = 'N'",
 
688
                     '-beginhook', sub {
 
689
                         if ($#_ < 2) {
 
690
                             #doing header;
 
691
                             print "<td></td>";
 
692
                         } else {
 
693
                             print "<td><img src=\"$NetSNMP::manager::redimage\"></td>\n";
 
694
                         }});
 
695
    }
 
696
 
 
697
    # get a list of tables we want to display
 
698
    my $tblh = getcursor($dbh, "SELECT * FROM hosttables where (host = '$host' and groupname = '$group')");
 
699
 
 
700
    # table data
 
701
    my($tablelist);
 
702
    while (  $tablelist = $tblh->fetchrow_hashref ) {
 
703
 
 
704
        displaytable($dbh, $tablelist->{'tablename'},
 
705
                     '-clauses', "where (host = '$host') order by oidindex",
 
706
                     '-dontdisplaycol', "select * from userprefs where user = '$remuser' and groupname = '$group' and tablename = ? and columnname = ? and displayit = 'N'",
 
707
                     '-sort', \&mykeysort,
 
708
                     '-dolink', \&linktodisplayinfo,
 
709
                     '-beginhook', \&printredgreen);
 
710
        if ($tablelist->{'keephistory'}) {
 
711
            my $q = self_url();
 
712
            $q =~ s/\?.*//;
 
713
            print "history: ";
 
714
            print "<a href=\"" . addtoken($q, "displayhistory=1&host=$host&group=$group&table=$tablelist->{'tablename'}hist") . "\">[table]</a>\n";
 
715
            print "<a href=\"" . addtoken($q, "displaygraph=1&host=$host&group=$group&table=$tablelist->{'tablename'}hist") . "\">[graph]</a>\n";
 
716
            print "<br>\n";
 
717
        }
 
718
    }
 
719
}
 
720
 
 
721
#
 
722
#  linktodisplayinfo(STRING):
 
723
#
 
724
#    returns a url to the appropriate displayinfo link if STRING is a
 
725
#    mib node.
 
726
#
 
727
sub linktodisplayinfo {
 
728
    return if (exists($NetSNMP::manager::myorder{shift}));
 
729
    return self_url() . "&displayinfo=" . shift;
 
730
}
 
731
 
 
732
# printredgreen(TABLENAME, DATA):
 
733
#
 
734
#   display a red or a green dot in a table dependent on the table's
 
735
#   values and associated expression
 
736
#
 
737
#   DATA is NULL when in a header row (displaying header names).
 
738
#
 
739
sub printredgreen {
 
740
    my $dbh = shift;
 
741
    my $tablename = shift;
 
742
    my $data = shift;
 
743
    my ($exprs, $expr, $img);
 
744
 
 
745
    if (!defined($data)) {
 
746
        #doing header;
 
747
        print "<td></td>";
 
748
        return;
 
749
    }
 
750
 
 
751
    my $cmd = "SELECT * FROM errorexpressions where (tablename = '$tablename')";
 
752
    print " $cmd\n" if ($NetSNMP::manager::verbose);
 
753
    ( $exprs = $dbh->prepare( $cmd ) )
 
754
        or die "\nnot ok: $DBI::errstr\n";
 
755
    ( $exprs->execute )
 
756
        or print( "\tnot ok: $DBI::errstr\n" );
 
757
 
 
758
    $img = $NetSNMP::manager::greenimage;
 
759
    while($expr = $exprs->fetchrow_hashref) {
 
760
        if ($dbh->do("select oidindex from $tablename where host = '$data->{host}' and oidindex = '$data->{oidindex}' and $expr->{expression}") ne "0E0") {
 
761
            $img = $NetSNMP::manager::redimage;
 
762
        }
 
763
    }
 
764
    print "<td><img src=$img></td>";
 
765
}
 
766
 
 
767
#
 
768
# display information about a given mib node as a table.
 
769
#
 
770
sub makemibtable {
 
771
    my $dispinfo = shift;
 
772
    # display information about a data type in a table
 
773
    my $mib = $SNMP::MIB{SNMP::translateObj($dispinfo)};
 
774
    print "<table $NetSNMP::manager::tableparms><tr><td>\n";
 
775
    foreach my $i (qw(label type access status units hint moduleID description enums)) {
 
776
#    foreach my $i (keys(%$mib)) {
 
777
        next if (!defined($$mib{$i}) || $$mib{$i} eq "");
 
778
        next if (ref($$mib{$i}) eq "HASH" && $#{keys(%{$$mib{$i}})} == -1);
 
779
        print "<tr><td>$i</td><td>";
 
780
        if (ref($$mib{$i}) eq "HASH") {
 
781
            print "<table $NetSNMP::manager::tableparms><tr><td>\n";
 
782
            foreach my $j (sort { $$mib{$i}{$a} <=> $$mib{$i}{$b} } keys(%{$$mib{$i}})) {
 
783
                print "<tr><td>$$mib{$i}{$j}</td><td>$j</td></tr>";
 
784
            }
 
785
            print "</table>\n";
 
786
        } else {
 
787
            print "$$mib{$i}";
 
788
        }
 
789
        print "</td></tr>\n";
 
790
    }
 
791
    print "</table>\n";
 
792
}
 
793
 
 
794
# given a user, get all the groups he belongs to.
 
795
sub getgroupsforuser {
 
796
    my (@ret, $cursor, $row);
 
797
    my ($dbh, $remuser) = @_;
 
798
    ( $cursor = $dbh->prepare( "SELECT * FROM usergroups where (user = '$remuser')"))
 
799
        or die "\nnot ok: $DBI::errstr\n";
 
800
    ( $cursor->execute )
 
801
        or print( "\tnot ok: $DBI::errstr\n" );
 
802
 
 
803
    while (  $row = $cursor->fetchrow_hashref ) {
 
804
        push(@ret, $row->{'groupname'});
 
805
    }
 
806
    @ret;
 
807
}
 
808
 
 
809
# given a host, get all the groups it belongs to.
 
810
sub gethostsforgroup {
 
811
    my (@ret, $cursor, $row);
 
812
    my ($dbh, $group) = @_;
 
813
    ( $cursor = $dbh->prepare( "SELECT * FROM hostgroups where (groupname = '$group')"))
 
814
        or die "\nnot ok: $DBI::errstr\n";
 
815
    ( $cursor->execute )
 
816
        or print( "\tnot ok: $DBI::errstr\n" );
 
817
 
 
818
    while (  $row = $cursor->fetchrow_hashref ) {
 
819
        push(@ret, $row->{'host'});
 
820
    }
 
821
    @ret;
 
822
}
 
823
 
 
824
# display the host add entry box
 
825
sub addhostentryform {
 
826
    my $group = shift;
 
827
    print "<form method=\"get\" action=\"" . self_url() . "\">\n";
 
828
    print "Add a new host to the group \"$group\": <input type=\"text\" name=\"newhost\"><br>";
 
829
    print "<input type=\"hidden\" name=\"group\" value=\"$group\">";
 
830
    print "<input type=submit value=\"Add Hosts\">\n";
 
831
    print "</form>";
 
832
}
 
833
 
 
834
#is an expert user?
 
835
sub isexpert {
 
836
    return 0;
 
837
}
 
838
 
 
839
#is remuser a admin?
 
840
sub isadmin {
 
841
    my ($dbh, $remuser, $group) = @_;
 
842
    return 0 if (!defined($remuser) || !defined($group));
 
843
    return 1 if ($dbh->do("select * from usergroups where user = '$remuser' and groupname = '$group' and isadmin = 'Y'") ne "0E0");
 
844
    return 0;
 
845
}
 
846
 
 
847
#is user a member of this group?
 
848
sub isuser {
 
849
    my ($dbh, $remuser, $group) = @_;
 
850
    return 0 if (!defined($remuser) || !defined($group));
 
851
    return 1 if ($dbh->do("select * from usergroups where user = '$remuser' and groupname = '$group'") ne "0E0");
 
852
    return 0;
 
853
}
 
854
 
 
855
# displayconfigarray(HOSTS, NAMES, CONFIG):
 
856
#
 
857
#   displays an array of generic check buttons to turn on/off certain
 
858
#   variables.
 
859
sub displayconfigarray {
 
860
    my $dbh = shift;
 
861
    my $hosts = shift;
 
862
    my $names = shift;
 
863
    my %config = @_;
 
864
 
 
865
    my $cmd;
 
866
    if ($config{'-check'}) {
 
867
        ( $cmd = $dbh->prepare( $config{'-check'} ) )
 
868
            or die "\nnot ok: $DBI::errstr\n";
 
869
    }
 
870
 
 
871
    print "<table $NetSNMP::manager::tableparms>\n";
 
872
    print "<tr><td></td>";
 
873
    my ($i, $j);
 
874
    foreach $j (@$names) {
 
875
        my $nj = $j;
 
876
        $nj = $j->[0] if ($config{'-arrayrefs'} || $config{'-arrayref2'});
 
877
        print "<td>$nj</td>";
 
878
    }
 
879
    foreach my $i (@$hosts) {
 
880
        my $ni = $i;
 
881
        $ni = $i->[0] if ($config{'-arrayrefs'} || $config{'-arrayref1'});
 
882
        print "<tr><td>$ni</td>";
 
883
        foreach $j (@$names) {
 
884
            my $nj = $j;
 
885
            $nj = $j->[0] if ($config{'-arrayrefs'} || $config{'-arrayref2'});
 
886
            my $checked = "checked" if (defined($cmd) && $cmd->execute($ni,$nj) ne "0E0");
 
887
            print "<td><input type=checkbox $checked value=y name=" . $config{prefix} . $ni . $nj . "></td>\n";
 
888
        }
 
889
        print "</tr>\n";
 
890
    }   
 
891
    print "</tr>";
 
892
    print "</table>";
 
893
}
 
894
 
 
895
sub adddefaulttables {
 
896
    my ($dbh, $names) = @_;
 
897
    my $row;
 
898
    # add in known expression tables.
 
899
    my $handle = getcursor($dbh, "SELECT * FROM errorexpressions");
 
900
 
 
901
    expr: 
 
902
    while($row = $handle->fetchrow_hashref) {
 
903
        foreach $i (@$names) {
 
904
            if ($i->[0] eq $row->{tablename}) {
 
905
                next expr;
 
906
            }
 
907
        }
 
908
        push @$names, [$row->{tablename}];
 
909
    }
 
910
}
 
911
 
 
912
#
 
913
# display the setup information page for a given group.
 
914
#
 
915
sub setupgroup {
 
916
    my $dbh = shift;
 
917
    my $group = shift;
 
918
    
 
919
    my ($hosts, $names) = gethostandgroups($dbh, $group);
 
920
    adddefaulttables($dbh, $names);
 
921
 
 
922
    print "<form method=\"post\" action=\"" . self_url() . "\">\n";
 
923
    print "<input type=hidden text=\"setupgroupsubmit\" value=\"y\">";
 
924
    displayconfigarray($dbh, $hosts, $names, 
 
925
                       -arrayrefs, 1,
 
926
                       -check, "select * from hosttables where (host = ? and tablename = ? and groupname = '$group')");
 
927
    print "<input type=hidden name=group value=\"$group\">\n";
 
928
    print "<input type=submit value=submit name=\"setupgroupsubmit\">\n";
 
929
    print "</form>";
 
930
}
 
931
 
 
932
# a wrapper around fetching arrays of everything in a table.
 
933
sub getarrays {
 
934
    my $dbh = shift;
 
935
    my $table = shift;
 
936
    my %config = @_;
 
937
    my $selectwhat = $config{'-select'} || "*";
 
938
    my $handle;
 
939
    
 
940
    $handle = getcursor($dbh, "SELECT $selectwhat FROM $table $config{-clauses}");
 
941
    return $handle->fetchall_arrayref;
 
942
}
 
943
 
 
944
#
 
945
# get a list of all tablenames and hostnames for a given group.
 
946
#
 
947
sub gethostandgroups {
 
948
    my $dbh = shift;
 
949
    my $group = shift;
 
950
    my ($tbnms);
 
951
 
 
952
    my $names = getarrays($dbh, 'hosttables', 
 
953
                          "-select", 'distinct tablename',
 
954
                          "-clauses", "where groupname = '$group'");
 
955
 
 
956
    my $hosts = getarrays($dbh, 'hostgroups', 
 
957
                          "-select", 'distinct host',
 
958
                          "-clauses", "where groupname = '$group'");
 
959
    
 
960
    return ($hosts, $names);
 
961
}
 
962
 
 
963
sub setupgroupsubmit {
 
964
    my $dbh = shift;
 
965
    my $group = shift;
 
966
    
 
967
    my ($hosts, $names) = gethostandgroups($dbh, $group);
 
968
    adddefaulttables($dbh, $names);
 
969
 
 
970
    foreach my $i (@$hosts) {
 
971
        $dbh->do("delete from hosttables where host = '${$i}[0]' and groupname = '$group'");
 
972
    }
 
973
    my $rep = $dbh->prepare("insert into hosttables(host,tablename,groupname) values(?,?,'$group')");
 
974
 
 
975
    foreach my $i (@$hosts) {
 
976
        foreach my $j (@$names) {
 
977
            if (param("${$i}[0]" . "${$j}[0]")) {
 
978
                print "test: ","${$i}[0] : ${$j}[0]<br>\n";
 
979
                $rep->execute("${$i}[0]", "${$j}[0]") || print "$! $DBI::errstr<br>\n";
 
980
            }
 
981
        }
 
982
    }
 
983
    
 
984
}
 
985
 
 
986
#
 
987
# save user pref data submitted by the user
 
988
#
 
989
sub setupusersubmit {
 
990
    my ($dbh, $remuser, $group) = @_;
 
991
    my $tables = getarrays($dbh, 'hosttables', 
 
992
                           "-select", 'distinct tablename',
 
993
                           "-clauses", "where groupname = '$group'");
 
994
    
 
995
    $dbh->do("delete from userprefs where user = '$remuser' and groupname = '$group'");
 
996
    my $rep = $dbh->prepare("insert into userprefs(user, groupname, tablename, columnname, displayit) values('$remuser', '$group', ?, ?, 'N')");
 
997
 
 
998
    my ($i, $j);
 
999
    foreach my $i (@$tables) {
 
1000
        my $sth = $dbh->prepare("select * from ${$i}[0] where 1 = 0");
 
1001
        $sth->execute();
 
1002
 
 
1003
        foreach $j (@{$sth->{NAME}}) {
 
1004
            if (param("${$i}[0]" . "$j")) {
 
1005
                $rep->execute("${$i}[0]", "$j");
 
1006
            }
 
1007
        }
 
1008
    }
 
1009
}
 
1010
 
 
1011
sub Exit {
 
1012
    my ($dbh, $group) = @_;
 
1013
    my $tq = self_url();
 
1014
    $tq =~ s/\?.*//;
 
1015
    print "<hr>\n";
 
1016
    print "<a href=\"$tq\">[TOP]</a>\n";
 
1017
    print "<a href=\"$tq?userprefs=1&group=$group\">[display options]</a>\n";
 
1018
    print "<a href=\"$tq?setuponcall=1\">[setup oncall schedule]</a>\n";
 
1019
    if (defined($group)) {
 
1020
        print "<a href=\"$tq?group=$group\">[group: $group]</a>\n";
 
1021
        print "<a href=\"$tq?group=$group&summarizegroup=1\">[summarize errors]</a>\n";
 
1022
    }
 
1023
    $dbh->disconnect() if (defined($dbh));
 
1024
    return OK();
 
1025
#    exit shift;
 
1026
}
 
1027
 
 
1028
#
 
1029
# setup user preferences by displaying a configuration array of
 
1030
# checkbuttons for each table.
 
1031
#
 
1032
sub setupuserpreferences {
 
1033
    my ($dbh, $remuser, $group) = @_;
 
1034
    my $tables = getarrays($dbh, 'hosttables', 
 
1035
                           "-select", 'distinct tablename',
 
1036
                           "-clauses", "where groupname = '$group'");
 
1037
 
 
1038
    print "<h3>Select the columns from the tables that you want to <b>hide</b> below and click on submit:</h3>\n";
 
1039
    print "<form method=\"post\" action=\"" . self_url() . "\">\n";
 
1040
 
 
1041
    my ($i, $j);
 
1042
    foreach my $i (@$tables) {
 
1043
        my $sth = $dbh->prepare("select * from ${$i}[0] where 1 = 0");
 
1044
        $sth->execute();
 
1045
        displayconfigarray($dbh, [${$i}[0]], $sth->{NAME},
 
1046
                           -check, "select * from userprefs where (tablename = ? and columnname = ? and user = '$remuser' and groupname = '$group' and displayit = 'N')");
 
1047
    print "<br>\n";
 
1048
    }
 
1049
    print "<input type=hidden name=group value=\"$group\">\n";
 
1050
    print "<input type=submit value=submit name=\"setupuserprefssubmit\">\n";
 
1051
    print "</form>";
 
1052
}