Initial checking from CVS

This commit is contained in:
Deon George 2011-01-14 01:45:19 +11:00
commit fe11dd5f51
70 changed files with 10950 additions and 0 deletions

70
INSTALL Normal file
View File

@ -0,0 +1,70 @@
$Header: /cvsroot/phptsmadmin/phpTSMadmin/INSTALL,v 1.5 2008/01/15 10:50:41 wurley Exp $
* Requirements
phpTSMadmin is a PHP5 application. It wont work on PHP4. If you are using CentOS 4 or RedHat
Enterprise Linux v4, then you can get PHP5 from the centosplus repository.
The requirements below are those used by RedHat Enterprise Linux v5.0 system. It is quite
possible that other versions of these components, or other distributions of Linux will also
work as well.
If you encounter any problems with other versions, then drop us an email with
the error messages, what you did and what you expected, and if we need to make some code changes
to get it to work, then we'll take a look.
* Apache 2.0.x
* PHP 5.1.x
* TSM Client 5.x (our tests were done on a 5.4.1 TSM server).
* Additional Requirements that are optional.
We also use a fantastic tool called JpGraph, that takes care of the Gantt charts. It is recommended that
you download and install that tool. You can get JpGraph at:
http://www.aditus.nu/jpgraph
You'll need at least v2.x our testing was with 2.3.
Once downloaded, untar jpgraph in the libs directory, then update your config.php to reflect the path.
* Installation
These steps assume that you have installed, configured and running:
* Linux server,
* Apache installed, configured and running,
* PHP installed, configured if necessary and running with apache,
* TSM client installed, configured and working.
* JpGraph (if you choose to use it - which you should).
1. Download the latest version.
You can download phpTSMadmin from sourceforge. http://phpTSMadmin.sf.net
2. Unpack the tar files in an appropriate directory.
cd /var/www/phpTSMadmin (or any other directory that you choose)
tar xzf phpTSMadmin-XXXX.tgz
3. Configure your webserver.
Find the sample apache config file in the contrib directory. Place that in
your /etc/httpd/conf.d directory.
Edit the sample apache config file as appropriate and restart your web server.
Also make sure that in your php.ini configuration file, you have set "memory_limit" to
at leat 16M. If this is set too low, then your grantt charts will fail to be created
and your apache error log will have "Allowed memory size of X bytes exhausted" error
messages.
4. Copy config.php.example in the config directory to config/config.php and edit to
suite your environment.
Edit the phpTSMadmin's config.php file, making sure you define:
* TSM client configuration
* Jpgraph path
5. Make the following directories.
mkdir htdocs/tmp; chmod 777 htdocs/tmp
6. Then, point your browser to your phpTSMadmin URL.
* For help
Drop me an email phptsmadmin-devel@lists.sourceforge.net.

341
LICENSE Normal file
View File

@ -0,0 +1,341 @@
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
License is intended to guarantee your freedom to share and change free
software--to make sure the software is free for all its users. This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it. (Some other Free Software Foundation software is covered by
the GNU Library General Public License instead.) You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
this service if you wish), that you receive source code or can get it
if you want it, that you can change the software or use pieces of it
in new free programs; and that you know you can do these things.
To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if you
distribute copies of the software, or if you modify it.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must give the recipients all the rights that
you have. You must make sure that they, too, receive or can get the
source code. And you must show them these terms so they know their
rights.
We protect your rights with two steps: (1) copyright the software, and
(2) offer you this license which gives you legal permission to copy,
distribute and/or modify the software.
Also, for each author's protection and ours, we want to make certain
that everyone understands that there is no warranty for this free
software. If the software is modified by someone else and passed on, we
want its recipients to know that what they have is not the original, so
that any problems introduced by others will not reflect on the original
authors' reputations.
Finally, any free program is threatened constantly by software
patents. We wish to avoid the danger that redistributors of a free
program will individually obtain patent licenses, in effect making the
program proprietary. To prevent this, we have made it clear that any
patent must be licensed for everyone's free use or not licensed at all.
The precise terms and conditions for copying, distribution and
modification follow.
GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License applies to any program or other work which contains
a notice placed by the copyright holder saying it may be distributed
under the terms of this General Public License. The "Program", below,
refers to any such program or work, and a "work based on the Program"
means either the Program or any derivative work under copyright law:
that is to say, a work containing the Program or a portion of it,
either verbatim or with modifications and/or translated into another
language. (Hereinafter, translation is included without limitation in
the term "modification".) Each licensee is addressed as "you".
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running the Program is not restricted, and the output from the Program
is covered only if its contents constitute a work based on the
Program (independent of having been made by running the Program).
Whether that is true depends on what the Program does.
1. You may copy and distribute verbatim copies of the Program's
source code as you receive it, in any medium, provided that you
conspicuously and appropriately publish on each copy an appropriate
copyright notice and disclaimer of warranty; keep intact all the
notices that refer to this License and to the absence of any warranty;
and give any other recipients of the Program a copy of this License
along with the Program.
You may charge a fee for the physical act of transferring a copy, and
you may at your option offer warranty protection in exchange for a fee.
2. You may modify your copy or copies of the Program or any portion
of it, thus forming a work based on the Program, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) You must cause the modified files to carry prominent notices
stating that you changed the files and the date of any change.
b) You must cause any work that you distribute or publish, that in
whole or in part contains or is derived from the Program or any
part thereof, to be licensed as a whole at no charge to all third
parties under the terms of this License.
c) If the modified program normally reads commands interactively
when run, you must cause it, when started running for such
interactive use in the most ordinary way, to print or display an
announcement including an appropriate copyright notice and a
notice that there is no warranty (or else, saying that you provide
a warranty) and that users may redistribute the program under
these conditions, and telling the user how to view a copy of this
License. (Exception: if the Program itself is interactive but
does not normally print such an announcement, your work based on
the Program is not required to print an announcement.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Program, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Program.
In addition, mere aggregation of another work not based on the Program
with the Program (or with a work based on the Program) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may copy and distribute the Program (or a work based on it,
under Section 2) in object code or executable form under the terms of
Sections 1 and 2 above provided that you also do one of the following:
a) Accompany it with the complete corresponding machine-readable
source code, which must be distributed under the terms of Sections
1 and 2 above on a medium customarily used for software interchange; or,
b) Accompany it with a written offer, valid for at least three
years, to give any third party, for a charge no more than your
cost of physically performing source distribution, a complete
machine-readable copy of the corresponding source code, to be
distributed under the terms of Sections 1 and 2 above on a medium
customarily used for software interchange; or,
c) Accompany it with the information you received as to the offer
to distribute corresponding source code. (This alternative is
allowed only for noncommercial distribution and only if you
received the program in object code or executable form with such
an offer, in accord with Subsection b above.)
The source code for a work means the preferred form of the work for
making modifications to it. For an executable work, complete source
code means all the source code for all modules it contains, plus any
associated interface definition files, plus the scripts used to
control compilation and installation of the executable. However, as a
special exception, the source code distributed need not include
anything that is normally distributed (in either source or binary
form) with the major components (compiler, kernel, and so on) of the
operating system on which the executable runs, unless that component
itself accompanies the executable.
If distribution of executable or object code is made by offering
access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.
4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
void, and will automatically terminate your rights under this License.
However, parties who have received copies, or rights, from you under
this License will not have their licenses terminated so long as such
parties remain in full compliance.
5. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Program or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Program (or any work based on the
Program), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Program or works based on it.
6. Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the
original licensor to copy, distribute or modify the Program subject to
these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
this License.
7. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Program at all. For example, if a patent
license would not permit royalty-free redistribution of the Program by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Program.
If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended to
apply and the section as a whole is intended to apply in other
circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system, which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
may add an explicit geographical distribution limitation excluding
those countries, so that distribution is permitted only in or among
countries not thus excluded. In such case, this License incorporates
the limitation as if written in the body of this License.
9. The Free Software Foundation may publish revised and/or new versions
of the General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the Program
specifies a version number of this License which applies to it and "any
later version", you have the option of following the terms and conditions
either of that version or of any later version published by the Free
Software Foundation. If the Program does not specify a version number of
this License, you may choose any version ever published by the Free Software
Foundation.
10. If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, write to the author
to ask for permission. For software which is copyrighted by the Free
Software Foundation, write to the Free Software Foundation; we sometimes
make exceptions for this. Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.
NO WARRANTY
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
REPAIR OR CORRECTION.
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Also add information on how to contact you by electronic and paper mail.
If the program is interactive, make it output a short notice like this
when it starts in an interactive mode:
Gnomovision version 69, Copyright (C) year name of author
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, the commands you use may
be called something other than `show w' and `show c'; they could even be
mouse-clicks or menu items--whatever suits your program.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the program, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
`Gnomovision' (which makes passes at compilers) written by James Hacker.
<signature of Ty Coon>, 1 April 1989
Ty Coon, President of Vice
This General Public License does not permit incorporating your program into
proprietary programs. If your program is a subroutine library, you may
consider it more useful to permit linking proprietary applications with the
library. If this is what you want to do, use the GNU Library General
Public License instead of this License.

1
VERSION Normal file
View File

@ -0,0 +1 @@
$Name: $

144
config/config.php Normal file
View File

@ -0,0 +1,144 @@
<?php
// $Header: /cvsroot/phptsmadmin/phpTSMadmin/config/config.php.example,v 1.9 2009/04/19 04:15:00 wurley Exp $
/** NOTE **
** Make sure that <?php is the FIRST line of this file!
** IE: There should NOT be any blank lines or spaces BEFORE <?php
**/
/**
* The phpTSMadmin config file
*
* This is where you can customise some of the phpTSMadmin defaults
* that are defined in config_default.php.
*
* To override a default, use the $config->custom variable to do so.
* For example, the default for defining the language in config_default.php
*
* $this->default->appearance['lang'] = array(
* 'desc'=>'Language',
* 'default'=>'auto');
*
* to override this, use $config->custom->appearance['lang'] = 'en';
*
* This file is also used to configure your TSM server connections.
*
* You must specify at least one TSM server there. You may add
* as many as you like. You can also specify your language, and
* many other options.
*
* NOTE: Commented out values in this file prefixed by //, represent the
* defaults that have been defined in config_default.php.
* Commented out values prefixed by #, dont reflect their default value, you can
* check config_default.php if you want to see what the default is.
*
* DONT change config_default.php, you changes will be lost by the next release
* of PTA. Instead change this file - as it will NOT be replaced by a new
* version of phpTSMadmin.
*/
/*********************************************/
/* Useful important configuration overrides */
/*********************************************/
/* If you are asked to put this application in debug mode, this is how you do it: */
# $config->custom->debug['level'] = 255;
# $config->custom->debug['syslog'] = true;
# $config->custom->debug['file'] = '/tmp/app_debug.log';
/* phpTSMadmin can encrypt the content of sensitive cookies if you set this
to a big random string. */
// $config->custom->session['blowfish'] = '';
/* The language setting. If you set this to 'auto', phpTSMadmin will attempt
to determine your language automatically. Otherwise, available lanaguages
are: 'ct', 'de', 'en', 'es', 'fr', 'it', 'nl', and 'ru'
Localization is not complete yet, but most strings have been translated.
Please help by writing language files. See lang/en.php for an example. */
// $config->custom->appearance['language'] = 'auto';
/* Our local timezone
This is to make sure that when we ask the system for the current time, we
get the right local time. If this is not set, all time() calculations will
assume UTC if you have not set PHP date.timezone. */
// $config->custom->appearance['timezone'] = null;
# $config->custom->appearance['timezone'] = 'Australia/Melbourne';
/* Path to JPGraph
You need to download JPGraph to display the graphical charts. You can get
it from http://www.aditus.nu/jpgraph. */
// $config->custom->lib['jpgraph'] = LIBDIR.'JpGraph';
/* Path to a temp directory that is serviced by the webserver. This directory
is where some JPGraph pictures are created. */
// $config->custom->image['path'] = HTDOCDIR.'tmp/';
/* Browser URL path to the image['path'] directory. */
// $config->custom->image['pathurl'] = 'tmp/';
/*********************************************/
/* Commands */
/*********************************************/
/* Command availability ; if you don't authorize a command the command
links will not be shown and the command action will not be permitted.
For better security, set also ACL in your ldap directory. */
// $config->custom->commands['all'] = array(
// 'home' => true,
// 'login' => true,
// 'logout' => true,
// 'register' => true
// );
/*********************************************/
/* Appearance */
/*********************************************/
/* If you want to choose the appearance of the tree, specify a class name which
inherits from the Tree class. */
// $config->custom->appearance['menu'] = "menu_html";
/*********************************************/
/* Define your servers in this section */
/*********************************************/
$servers = new Datastore;
/* A convenient name that will appear in the tree viewer and throughout
phpTSMadmin to identify this LDAP server to users. */
/* $servers->NewServer('tsm') must be called before each new TSM server
declaration. It will return a number, which is the instance number. It must
be used in the setValue declaration. */
$servers->NewServer('tsm');
/* A name for your TSM server, it will appear in on the page for the TSM server
being used. If you have multiple TSM servers, it will be the name in the
drop down list. */
$servers->setValue('server','name','TSM Server');
/* The stanza used to connect to this TSM server, when calling dsmadmc. This is
the value for the SErvername attribute in your dsm.opt file. */
// $servers->setValue('server','stanza',null);
/* Path to your dsmadmc binary. */
// $servers->setValue('system','dsmadmc','/opt/tivoli/tsm/client/ba/bin/dsmadmc');
/* Filename for the error dsmadmc error log */
// $servers->setValue('system','errorlog','/tmp/pta-tsm-errorlog.log');
/* Age of tapes to consider for alerting (to rotate them) */
// $servers->setValue('system','tapeage',180);
/**************************************************************************
* If you want to configure additional TSM servers, do so below. Remove *
* the commented lines and use this section as a template for all your *
* other servers. *
**************************************************************************/
/*
$servers->NewServer('tsm');
$servers->setValue('server','name','Another TSM Server');
*/
?>

144
config/config.php.example Normal file
View File

@ -0,0 +1,144 @@
<?php
// $Header: /cvsroot/phptsmadmin/phpTSMadmin/config/config.php.example,v 1.9 2009/04/19 04:15:00 wurley Exp $
/** NOTE **
** Make sure that <?php is the FIRST line of this file!
** IE: There should NOT be any blank lines or spaces BEFORE <?php
**/
/**
* The phpTSMadmin config file
*
* This is where you can customise some of the phpTSMadmin defaults
* that are defined in config_default.php.
*
* To override a default, use the $config->custom variable to do so.
* For example, the default for defining the language in config_default.php
*
* $this->default->appearance['lang'] = array(
* 'desc'=>'Language',
* 'default'=>'auto');
*
* to override this, use $config->custom->appearance['lang'] = 'en';
*
* This file is also used to configure your TSM server connections.
*
* You must specify at least one TSM server there. You may add
* as many as you like. You can also specify your language, and
* many other options.
*
* NOTE: Commented out values in this file prefixed by //, represent the
* defaults that have been defined in config_default.php.
* Commented out values prefixed by #, dont reflect their default value, you can
* check config_default.php if you want to see what the default is.
*
* DONT change config_default.php, you changes will be lost by the next release
* of PTA. Instead change this file - as it will NOT be replaced by a new
* version of phpTSMadmin.
*/
/*********************************************/
/* Useful important configuration overrides */
/*********************************************/
/* If you are asked to put this application in debug mode, this is how you do it: */
# $config->custom->debug['level'] = 255;
# $config->custom->debug['syslog'] = true;
# $config->custom->debug['file'] = '/tmp/app_debug.log';
/* phpTSMadmin can encrypt the content of sensitive cookies if you set this
to a big random string. */
// $config->custom->session['blowfish'] = '';
/* The language setting. If you set this to 'auto', phpTSMadmin will attempt
to determine your language automatically. Otherwise, available lanaguages
are: 'ct', 'de', 'en', 'es', 'fr', 'it', 'nl', and 'ru'
Localization is not complete yet, but most strings have been translated.
Please help by writing language files. See lang/en.php for an example. */
// $config->custom->appearance['language'] = 'auto';
/* Our local timezone
This is to make sure that when we ask the system for the current time, we
get the right local time. If this is not set, all time() calculations will
assume UTC if you have not set PHP date.timezone. */
// $config->custom->appearance['timezone'] = null;
# $config->custom->appearance['timezone'] = 'Australia/Melbourne';
/* Path to JPGraph
You need to download JPGraph to display the graphical charts. You can get
it from http://www.aditus.nu/jpgraph. */
// $config->custom->lib['jpgraph'] = LIBDIR.'JpGraph';
/* Path to a temp directory that is serviced by the webserver. This directory
is where some JPGraph pictures are created. */
// $config->custom->image['path'] = HTDOCDIR.'tmp/';
/* Browser URL path to the image['path'] directory. */
// $config->custom->image['pathurl'] = 'tmp/';
/*********************************************/
/* Commands */
/*********************************************/
/* Command availability ; if you don't authorize a command the command
links will not be shown and the command action will not be permitted.
For better security, set also ACL in your ldap directory. */
// $config->custom->commands['all'] = array(
// 'home' => true,
// 'login' => true,
// 'logout' => true,
// 'register' => true
// );
/*********************************************/
/* Appearance */
/*********************************************/
/* If you want to choose the appearance of the tree, specify a class name which
inherits from the Tree class. */
// $config->custom->appearance['menu'] = "menu_html";
/*********************************************/
/* Define your servers in this section */
/*********************************************/
$servers = new Datastore;
/* A convenient name that will appear in the tree viewer and throughout
phpTSMadmin to identify this LDAP server to users. */
/* $servers->NewServer('tsm') must be called before each new TSM server
declaration. It will return a number, which is the instance number. It must
be used in the setValue declaration. */
$servers->NewServer('tsm');
/* A name for your TSM server, it will appear in on the page for the TSM server
being used. If you have multiple TSM servers, it will be the name in the
drop down list. */
$servers->setValue('server','name','TSM Server');
/* The stanza used to connect to this TSM server, when calling dsmadmc. This is
the value for the SErvername attribute in your dsm.opt file. */
// $servers->setValue('server','stanza',null);
/* Path to your dsmadmc binary. */
// $servers->setValue('system','dsmadmc','/opt/tivoli/tsm/client/ba/bin/dsmadmc');
/* Filename for the error dsmadmc error log */
// $servers->setValue('system','errorlog','/tmp/pta-tsm-errorlog.log');
/* Age of tapes to consider for alerting (to rotate them) */
// $servers->setValue('system','tapeage',180);
/**************************************************************************
* If you want to configure additional TSM servers, do so below. Remove *
* the commented lines and use this section as a template for all your *
* other servers. *
**************************************************************************/
/*
$servers->NewServer('tsm');
$servers->setValue('server','name','Another TSM Server');
*/
?>

12
contrib/http.phpTSMadmin.conf Executable file
View File

@ -0,0 +1,12 @@
# phpTSMadmin
<Directory "/var/www/phpTSMadmin">
AllowOverride AuthConfig Limit
</Directory>
<VirtualHost *>
ServerName phptsmadmin.mydomain.net
DocumentRoot /var/www/phpTSMadmin
ErrorLog /var/log/httpd/phptsmadmin.mydomain.net-error_log
TransferLog /var/log/httpd/phptsmadmin.mydomain.net-access_log
</VirtualHost>

15
docs/CREDITS Normal file
View File

@ -0,0 +1,15 @@
$Header: /cvsroot/phptsmadmin/phpTSMadmin/docs/CREDITS,v 1.2 2004/10/03 05:35:28 wurley Exp $
----------------------------
| phpTSMadmin contributors |
============================
Developers:
* Deon George (wurley@users.sf.net)
Other OS software:
* This script uses the template class from phplib - all credit to those developers.
For more information on phplib, check out their website http://phplib.shonline.de
* JPGraph is used to draw the gantt charts, you'll need to get it from http://www.aditus.nu/jpgraph/
If you would like to assist, contribute, develop, help then drop me an email.

61
htdocs/cmd.php Normal file
View File

@ -0,0 +1,61 @@
<?php
// $Header: /cvsroot/phptsmadmin/phpTSMadmin/htdocs/cmd.php,v 1.2 2009/04/19 03:52:21 wurley Exp $
/**
* Main command page for this application
* All pages are rendered through this script.
*
* @package leenooksApp
* @subpackage Page
*/
/**
*/
require_once './common.php';
$www['cmd'] = get_request('cmd','REQUEST');
$www['meth'] = get_request('meth','REQUEST');
ob_start();
switch ($www['cmd']) {
case '_debug' :
debug_dump($_REQUEST,1);
break;
default :
if (defined('HOOKSDIR') && file_exists(HOOKSDIR.$www['cmd'].'.php'))
$app['script_cmd'] = HOOKSDIR.$www['cmd'].'.php';
elseif (defined('HTDOCDIR') && file_exists(HTDOCDIR.$www['cmd'].'.php'))
$app['script_cmd'] = HTDOCDIR.$www['cmd'].'.php';
elseif (file_exists('welcome.php'))
$app['script_cmd'] = 'welcome.php';
else
$app['script_cmd'] = null;
}
if (DEBUG_ENABLED)
debug_log('Ready to render page for command [%s,%s].',128,__FILE__,__LINE__,__METHOD__,$www['cmd'],$app['script_cmd']);
# Create page.
# Set the index so that we render the right menu tree.
$www['page'] = new page($app['server']->getIndex());
if ($app['script_cmd'])
include $app['script_cmd'];
# Capture the output and put into the body of the page.
$www['body'] = new block();
$www['body']->SetBody(ob_get_contents());
$www['page']->block_add('body',$www['body']);
ob_end_clean();
if ($www['meth'] == 'ajax')
$www['page']->show(get_request('frame','REQUEST',false,'BODY'),true);
else
$www['page']->display();
?>

16
htdocs/common.php Normal file
View File

@ -0,0 +1,16 @@
<?php
// $Header: /cvsroot/phptsmadmin/phpTSMadmin/htdocs/common.php,v 1.2 2009/04/19 03:53:40 wurley Exp $
/**
* This script provides a convienent method to call the proper common.php
*
* @package leenooksApp
*/
/**
*/
if (! defined('LIBDIR'))
define('LIBDIR',sprintf('%s/',realpath('../lib/')));
require_once LIBDIR.'common.php';
?>

862
htdocs/css/style.css Normal file
View File

@ -0,0 +1,862 @@
/* $Header: /cvsroot/phptsmadmin/phpTSMadmin/htdocs/css/style.css,v 1.5 2009/04/19 04:00:59 wurley Exp $ */
/* Global Page */
table.page {
font-weight: normal;
color: #000000;
font-family: bitstream vera sans,luxi sans,verdana,geneva,arial,helvetica,sans-serif;
background-color: #FFFFFF;
font-size: 13px;
empty-cells: hide;
}
/* Global Page - Defaults */
/* A HREF Links */
table.page a {
color: #0000AA;
text-decoration: none;
}
table.page a:hover {
text-decoration: none;
}
table.page a img {
border: 0px;
}
/* Global Page - Logo & Title */
table.page tr.head {
text-align: center;
color: #FFFFFF;
background-color: #001188;
font-weight: bold;
font-size: 11px;
height: 25px;
}
table.page tr.head img.logo {
vertical-align: middle;
text-align: center;
width: 100px;
height: 60px;
}
table.page tr.pagehead td.imagetop {
width: 100%;
vertical-align: bottom;
}
/* Global Page - Control Line */
table.page tr.control td {
border-top: 1px solid #AAAACC;
border-bottom: 1px solid #AAAACC;
}
/* Global Page - Control Line Menu Items */
table.page table.control {
table-layout: fixed;
width: 100%;
}
table.page table.control td {
border-top: 0px;
border-bottom: 0px;
width: 30px;
padding: 0px;
padding-top: 2px;
padding-bottom: 2px;
text-align: left;
vertical-align: top;
font-size: 11px;
font-weight: bold;
}
table.page table.control img {
width: 24px;
height: 24px;
}
table.page table.control a {
color: #000000;
}
table.page table.control a:hover {
text-decoration: none;
background-color: #FFFFFF;
color: #0000AA;
}
table.page table.control td.spacer {
width: 20%;
}
table.page table.control td.logo {
text-align: right;
width: 10%;
}
table.page table.control td.logo img.logo {
vertical-align: middle;
text-align: right;
width: 100px;
height: 50px;
}
/* Global Page - Menu */
table.page td.menu {
border-right: 1px solid #AAAACC;
vertical-align: top;
background-color: #FCFCFE;
width: 10%;
}
/* Global Page - Main Body */
table.page td.body {
vertical-align: top;
width: 100%;
background-color: #FCFCFE;
}
/* Global Page - Main Body System Message */
table.page table.sysmsg {
border-bottom: 2px solid #AAAACC;
width: 100%;
}
table.page table.sysmsg td.head {
font-size: small;
text-align: left;
font-weight: bold;
}
table.page table.sysmsg td.body {
font-weight: normal;
}
table.page table.sysmsg td.icon {
text-align: center;
vertical-align: top;
}
/* Global Page - Main Body */
table.page table.body {
font-weight: normal;
background-color: #FCFCFE;
width: 100%;
}
table.page table.body h3.title {
text-align: center;
margin: 0px;
padding: 10px;
color: #FFFFFF;
background-color: #000088;
border: 1px solid #000000;
font-weight: normal;
font-size: 150%;
}
table.page table.body h3.subtitle {
text-align: center;
margin: 0px;
margin-bottom: 15px;
font-size: 75%;
color: #FFFFFF;
border-bottom: 1px solid #000000;
border-left: 1px solid #000000;
border-right: 1px solid #000000;
background: #000088;
padding: 4px;
font-weight: normal;
}
table.page table.body td.spacer {
border-top: 2px solid #AAAACC;
padding: 0px;
font-size: 5px;
}
table.page table.body td.head {
font-weight: bold;
}
table.page table.body td.foot {
font-size: small;
border-top: 1px solid #AAAACC;
border-bottom: 1px solid #AAAACC;
}
/* Global Page Footer */
table.page tr.foot td {
border-top: 1px solid #AAAACC;
font-weight: bold;
font-size: 12px;
text-align: right;
}
/* Global Page - Other Layouts */
/* Server Select */
table.page table.server_select {
font-weight: bold;
font-size: 13px;
color: #000000;
}
/* Individual table layouts */
/* Menu */
table.menu {
}
table.menu tr.server td.icon {
vertical-align: top;
}
table.menu tr.server td.name {
padding-right: 10px;
vertical-align: top;
}
table.menu tr.server td {
padding-top: 5px;
font-size: 18px;
text-align: left;
padding-right: 0px;
white-space: nowrap;
}
table.menu tr.links td {
white-space: nowrap;
}
table.menu tr.links td td.ds_option {
vertical-align: top;
text-align: center;
padding-top: 0px;
padding-bottom: 0px;
padding-left: 3px;
padding-right: 3px;
}
table.menu tr.links td td.ds_option img {
height: 22px;
width: 22px;
}
table.menu tr.links a {
color: #000000;
text-decoration: none;
font-size: 11px;
}
table.menu tr.links a:hover {
text-decoration: none;
background-color: #FFFFFF;
color: #000000;
}
table.menu tr.option td.expander {
text-align: center;
width: 22px;
max-width: 22px;
min-width: 22px;
white-space: nowrap;
}
table.menu tr.option td.icon {
text-align: center;
width: 22px;
max-width: 22px;
min-width: 22px;
white-space: nowrap;
}
table.menu tr.option td.item a {
font-size: 13px;
color: #000000;
}
table.menu tr.option td.item a:hover {
font-size: 13px;
color: #841212;
background-color: #FFF0C0;
text-decoration: none;
}
table.menu tr.option td.item span.count {
font-size: 13px;
color: #000000;
}
table.menu td.links a {
color: #0000AA;
text-align: center;
}
table.menu td.create a {
font-size: 13px;
color: #000000;
}
table.menu td.create a:hover {
font-size: 13px;
color: #841212;
background-color: #FFF0C0;
text-decoration: none;
}
table.menu td.links a:hover {
text-decoration: none;
color: blue;
}
table.menu td.links a img {
width: 22px;
height: 22px;
}
table.menu td.blank {
font-size: 1px;
}
table.menu td.spacer {
width: 22px;
}
table.menu td.logged_in {
font-size: 10px;
white-space: nowrap;
}
table.menu td.logged_in a {
font-size: 11px;
}
table.menu td.logged_in a:hover {
color: #841212;
background-color: #FFF0C0;
text-decoration: none;
}
/* Tree Global Defaults */
table.menu tr td {
padding: 0px;
}
table.menu a {
text-decoration: none;
color: #000000;
}
table.menu a:hover {
text-decoration: underline;
color: blue;
}
/* Standard Form */
table.forminput {
background-color: #F9F9FA;
padding: 10px;
border: 1px solid #AAAACC;
}
table.forminput td.title {
text-align: center;
font-weight: bold;
}
table.forminput td.subtitle {
text-align: center;
font-weight: normal;
font-size: small;
}
table.forminput tr td.heading {
font-weight: bold;
}
table.forminput td.small {
font-size: 80%;
}
table.forminput td.top {
vertical-align: top;
}
table.forminput input.val {
width: 350px;
border: 1px solid #AAAACC;
}
table.forminput input.roval {
width: 350px;
border: none;
}
table.forminput td.icon {
width: 16px;
text-align: center;
}
table.forminput td.icon img {
border: 0px;
}
table.forminput td.label {
text-align: left;
font-size: 13px;
}
/* Menu on top of entry form */
table.menu {
font-size: 14px;
}
table.menu td.icon {
width: 16px;
text-align: center;
}
/* Edit */
div.add_value {
font-size: 12px;
margin: 0px;
padding: 0px;
}
/* Edit Entry */
table.entry {
border-collapse: collapse;
border-spacing: 0px;
empty-cells: show;
}
table.entry input {
margin: 1px;
}
table.entry input.value {
color: #000000;
font-size: 14px;
width: 350px;
background-color: #FFFFFF;
}
table.entry div.helper {
text-align: left;
white-space: nowrap;
background-color: #FFFFFF;
color: #888;
font-size: 14px;
font-weight: normal;
}
table.entry input.roval {
font-size: 14px;
width: 350px;
background-color: #FFFFFF;
color: #000000;
border: none;
}
table.entry textarea.value {
font-size: 14px;
width: 350px;
background-color: #FFFFFF;
color: #000000;
}
table.entry textarea.roval {
font-size: 14px;
width: 350px;
background-color: #FFFFFF;
color: #000000;
border: none;
}
table.entry tr td {
padding: 4px;
padding-right: 0px;
}
table.entry tr td.heading {
border-top: 3px solid #C0C0C0;
font-weight: bold;
}
table.entry tr td.note {
text-align: right;
background-color: #E0E0E0;
}
table.entry tr td.title {
background-color: #E0E0E0;
vertical-align: top;
font-weight: bold;
}
table.entry tr td.title a {
text-decoration: none;
color: #000000;
}
table.entry tr td.title a:hover {
text-decoration: underline;
color: #016;
}
table.entry tr td.value {
text-align: left;
vertical-align: middle;
padding-bottom: 10px;
padding-left: 50px;
}
/** When an attr is updated, it is highlighted to indicate such */
table.entry tr.updated td.title {
border-top: 1px dashed #AAAA88;
border-left: 1px dashed #AAAA88;
background-color: #999988;
}
table.entry tr.updated td.note {
border-top: 1px dashed #AAAA88;
border-right: 1px dashed #AAAA88;
background-color: #999988;
}
/** An extra row that sits at the bottom of recently modified attrs to encase them in dashes */
table.entry tr.updated td.bottom {
border-top: 1px dashed #AAAA88;
}
/** Formatting for the value cell when it is the attribute that has been recently modified */
table.entry tr.updated td.value {
border-left: 1px dashed #AAAA88;
border-right: 1px dashed #AAAA88;
}
/* Need to prevent sub-tables (like the one in which jpegPhotos are displayed)
* from drawing borders as well. */
table.entry tr.updated td table td {
border: 0px;
}
table.entry tr.noinput {
background: #E0E0E0;
}
span.hint {
font-size: small;
font-weight: normal;
color: #888;
}
/* Login Box */
#login {
background: url('../images/uid.png') no-repeat 0 1px;
background-color: #FAFAFF;
color: #000000;
padding-left: 17px;
}
#login:focus {
background-color: #F0F0FF;
color: #000000;
}
#login:disabled {
background-color: #DDDDFF;
color: #000000;
}
#password {
background: url('../images/key.png') no-repeat 0 1px;
background-color: #FAFAFF;
color: #000000;
padding-left: 17px;
}
#password:focus {
background-color: #F0F0FF;
color: #000000;
}
#password:disabled {
background-color: #DDDDFF;
color: #000000;
}
#generic {
background-color: #FAFAFF;
color: #000000;
padding-left: 17px;
}
#generic:focus {
background-color: #F0F0FF;
color: #000000;
}
#generic:disabled {
background-color: #DDDDFF;
color: #000000;
}
/* After input results */
div.execution_time {
font-size: 75%;
font-weight: normal;
text-align: left;
}
table.result {
width: 100%;
vertical-align: top;
empty-cells: show;
border: 1px solid #AAAACC;
border-spacing: 0px;
background-color: #F2F2FF;
}
table.result td.titlel {
text-align: left;
font-weight: bold;
}
table.result td.titlec {
text-align: center;
font-weight: bold;
}
table.result td.titler {
text-align: right;
font-weight: bold;
}
table.result tr.heading {
vertical-align: top;
}
table.result tr.list_title {
background-color: #FFFFFF;
}
table.result tr.list_title td.icon {
text-align: center;
vertical-align: top;
}
table.result tr.list_item {
background-color: #FFFFFF;
}
table.result tr.list_item td.blank {
width: 25px;
}
table.result tr.list_item td.heading {
vertical-align: top;
color: gray;
width: 10%;
font-size: 12px;
}
table.result tr.list_item td.value {
color: #000000;
font-size: 12px;
}
table.result_table {
border: 1px solid #AAAACC;
border-collapse: collapse;
empty-cells: show;
}
table.result_table td {
font-size: 12px;
vertical-align: top;
border: 1px solid #AAAACC;
padding: 4px;
}
table.result_table th {
border: 1px solid #AAAACC;
padding: 10px;
padding-left: 20px;
padding-right: 20px;
}
table.result_table tr.highlight {
background-color: #EEEBBB;
}
table.result_table tr.highlight td {
border: 1px solid #AAAACC;
font-weight: bold;
padding-top: 5px;
padding-bottom: 5px;
padding-left: 10px;
padding-right: 10px;
}
table.result_table td.heading {
color: #FFFFFF;
background-color: #000088;
font-size: 15px;
}
table.result_table td.value {
color: #000000;
background-color: #E0E0E0;
}
table.result_table tr.heading {
color: #FFFFFF;
background-color: #000088;
font-size: 15px;
font-weight: bold;
}
table.result_table tr.heading a {
color: #FFFFFF;
font-size: 15px;
font-weight: bold;
}
table.result_table tr.heading td {
border: 1px solid #AAAACC;
font-weight: normal;
padding-top: 5px;
padding-bottom: 5px;
padding-left: 10px;
padding-right: 10px;
}
table.result_table td.titlel {
text-align: left;
font-weight: bold;
}
table.result_table td.titlec {
text-align: center;
font-weight: bold;
}
table.result_table td.titler {
text-align: right;
font-weight: bold;
}
table.result_table tr.even {
background-color: #E0E0E0;
}
table.result_table tr.even td {
border: 1px solid #AAAACC;
font-weight: normal;
padding-top: 5px;
padding-bottom: 5px;
padding-left: 10px;
padding-right: 10px;
}
table.result_table tr.even td.title {
font-weight: bold;
}
table.result_table tr.odd {
background-color: #F0F0F0;
}
table.result_table tr.odd td {
border: 1px solid #AAAACC;
font-weight: normal;
padding-top: 5px;
padding-bottom: 5px;
padding-left: 10px;
padding-right: 10px;
}
table.result_table tr.odd td.title {
font-weight: bold;
}
table.result_table ul.list {
margin: 5px;
margin-left: 0px;
padding-left: 20px;
}
table.result_table ul.list li {
margin-left: 0px;
padding-left: 0px;
}
table.result_table ul.list li small {
font-size: 75%;
color: #707070;
}
table.result_table ul.list li small a {
color: #7070C0;
}
/* Error Dialog Box */
table.error {
width: 500px;
border: 1px solid #AA0000;
background-color: #FFF0F0;
}
table.error th {
background-color: #AA0000;
border: 0px;
color: #FFFFFF;
font-size: 14px;
font-weight: bold;
text-align: center;
vertical-align: middle;
width: 100%;
}
table.error th.img {
vertical-align: middle;
text-align: center;
}
table.error td {
border: 0px;
background-color: #FFF0F0;
padding: 2px;
text-align: left;
vertical-align: top;
}
/* Popup Window */
div.popup h3.subtitle {
text-align: center;
margin: 0px;
margin-bottom: 15px;
color: #FFFFFF;
border-bottom: 1px solid #000000;
border-left: 1px solid #000000;
border-right: 1px solid #000000;
background: #000088;
padding: 4px;
font-weight: normal;
}
span.good {
color: green;
}
span.bad {
color: red;
}
span.value {
font-weight: bold;
}

319
htdocs/devclass.info.php Normal file
View File

@ -0,0 +1,319 @@
<?php
// $Header: /cvsroot/phptsmadmin/phpTSMadmin/htdocs/devclass.info.php,v 1.13 2009/04/19 03:53:40 wurley Exp $
# Required Libraries
require './common.php';
# @todo: Graph storage by storage pool
# Defaults
$devclasses = objectCache('devclasses');
$volumes = objectCache('volumes');
$drives = objectCache('drives');
$stgps = objectCache('stgps');
$occupancy = objectCache('occupancy');
$nodes = objectCache('nodes');
# Start
echo 'Show device class';
echo '<form action="cmd.php">';
printf('<input type="hidden" name="cmd" value="%s" />',get_request('cmd','REQUEST'));
printf('<input type="hidden" name="index" value="%s" />',$app['server']->getIndex());
echo '<select name="devclass" onchange="javascript:submit()">';
echo '<option value="">&nbsp;</option>';
foreach ($devclasses->getDevClasses() as $devc => $devclass) {
printf('<option value="%s" %s>%s</option>',
$devclass->getName(),
(isset($_REQUEST['devclass']) && ($_REQUEST['devclass'] == $devclass->getName())) ? 'selected' : '',
$devclass->getName());
}
echo '</select>';
echo '</form>';
if (isset($_REQUEST['devclass']) && trim($_REQUEST['devclass']))
foreach ($devclasses->getDevClasses() as $devc => $devclass) {
if ($_REQUEST['devclass'] != $devclass->getName())
continue;
echo '<table width="100%" class="page_detail" border=0>';
printf(_('<tr><td>Device Class</td><td><b>%s</b></td><td>&nbsp;</td></tr>'),$devc);
printf('<tr><td>Type</td><td>'.
classValue(_('%s %s media is used for this device class.'),'value').
'</td><td>&nbsp;</td></tr>',
$devclass->access,
$devclass->type);
if (trim($devclass->library)) {
printf('<tr><td>Library</td><td>'.
classValue(_('%s library is used to store this media.'),'value').
'</td><td>&nbsp;</td></tr>',
$devclass->library);
printf('<tr><td>&nbsp;</td><td>'.
classValue(_('%s drives defined in this library.'),'value').
'</td><td>&nbsp;</td></tr>',
count($drives->getDrives($devclass->library)));
}
if (trim($devclass->dir))
printf('<tr><td>Local Directory</td><td>'.
classValue(_('%s directory will contain %s volumes for this device class.'),'value').
'</td><td>&nbsp;</td></tr>',
$devclass->dir,$devclass->capacity);
echo '</table>';
echo '<br />';
printf(_('Storage Pools using device class %s.').'<br />',$devc);
$stgcount = 0;
foreach ($stgps->getStoragePools() as $stgp => $stgpool) {
# Ignore storage pools not of this device class.
if ($stgpool->devclass != $devc) continue;
echo '<table width="100%" class="result" border=0>';
# Title
echo "\n\n";
printf('<tr><td colspan=2 class="titlel">%s - %s (%s)</td><td class="titlec">&nbsp;</td></tr>',
$stgpool->getName(),$stgpool->type,$stgpool->access);
# Utlisation and Migration details
echo "\n\n";
switch ($stgpool->type) {
case 'PRIMARY' :
switch ($devclass->access) {
case 'Sequential' :
printf('<tr><td>&nbsp;</td><td>'.
classValue(_('%s%% storage capacity utilised with %s%% volumes used.'),
'value').
'</td><td>&nbsp;</td></tr>',
$stgpool->utilisation,$stgpool->migratable);
break;
case 'Random' :
printf('<tr><td>&nbsp;</td><td>'.
classValue(_('%s%% storage capacity utilised with %s%% migratable data.'),
'value').
'</td><td>&nbsp;</td></tr>',
$stgpool->utilisation,$stgpool->migratable);
break;
default :
printf('<tr><td colspan=2>Unknown access strategy %s.</td><td>',$devclass->access);
}
break;
case 'COPY' :
printf('<tr><td>&nbsp;</td><td>'.
classValue(_('%s%% storage capacity utilised.'),'value').
'</td><td>&nbsp;</td></tr>',
$stgpool->utilisation);
break;
default :
printf('<tr><td colspan=2><b>%s</b> %s.</td><td>',
_('Unknown pooltype'),$stgpool->type);
}
# Max object size
echo "\n\n";
if ($stgpool->maxsize)
printf('<tr><td>&nbsp;</td><td>'.
classValue(_('%3.2fMB Maximum Object Size.'),'value').
'</td><td>&nbsp;</td></tr>',
$stgpool->maxsize/1024/1024);
if ($stgpool->reclaim)
printf('<tr><td>&nbsp;</td><td>'.
classValue(_('%s%% wasted space is required before reclaimation. Reclamation will use %s'),
'value').
'</td><td>&nbsp;</td></tr>',
$stgpool->reclaim,($stgpool->reclaimstgp ? $stgpool->reclaimstgp : $stgp));
if ($stgpool->reclaimrunning)
printf('<tr><td>&nbsp;</td><td>'.
_('Reclamation IS currently running.').
'</td><td>&nbsp;</td></tr>');
if ($stgpool->reuse)
printf('<tr><td>&nbsp;</td><td>'.
classValue(_('%s days must pass before volumes will be reused.'),'value').
'</td><td>&nbsp;</td></tr>',
$stgpool->reuse);
# Migration details
if ($stgpool->nextstgp)
printf('<tr><td>&nbsp;</td><td>'.
classValue(_('Migration to %s will occur at %s%% (stopping at %s%%)'),'value').
'</td><td>&nbsp;</td></tr>',
$stgpool->nextstgp,$stgpool->migr['hi'],$stgpool->migr['low']);
if ($stgpool->migr['running'])
printf('<tr><td>&nbsp;</td><td>'.
classValue(_('Migration IS currently running. %sMB Migrated %ss'),'value').
'</td><td>&nbsp;</td></tr>',
$stgpool->migr['mb'],$stgpool->migr['sec']);
# Collocation Information
if ($stgpool->collocate)
printf('<tr><td>&nbsp;</td><td>'.
classValue(_('%s Collocation.'),'value').
'</td><td>&nbsp;</td></tr>',
$stgpool->collocate);
# Disk Caching.
if ($stgpool->cache)
printf('<tr><td>&nbsp;</td><td>'.
classValue(_('%s Migration caching.'),'value').
'</td><td>&nbsp;</td></tr>',
$stgpool->cache);
$stgcount++;
echo '<tr><td>&nbsp;</td></tr>';
# Volume information.
echo "\n\n";
switch ($devclass->type) {
case 'DISK' :
if ($volumes->getStoragePoolVolumes($stgpool->getName()))
foreach ($volumes->getStoragePoolVolumes($stgpool->getName()) as $volume) {
printf('<tr><td>&nbsp;</td><td>'.
classValue(_('Vol %s (%s%% %s) - %s.'),'value').
'</td><td>&nbsp;</td></tr>',
$volume->getName(),$volume->utilisation,
$volume->status['volume'],
$volume->access);
}
break;
default :
# Scratch Media
$temp = '';
if (count($volumes->getStoragePoolScratchVolumes($stgpool->getName())))
$temp .= sprintf('<tr><td>&nbsp;</td><td>'.
classValue(_('%s scratch media in use (of %s).'),'value').
'</td><td>&nbsp;</td></tr>',
count($volumes->getStoragePoolScratchVolumes($stgpool->getName())),$stgpool->maxscratch);
if (count($volumes->getStoragePoolDefinedVolumes($stgpool->getName())))
$temp .= sprintf('<tr><td>&nbsp;</td><td>'.
classValue(_('%s defined media in use.'),'value').
'</td><td>&nbsp;</td></tr>',
count($volumes->getStoragePoolDefinedVolumes($stgpool->getName())));
if ($temp) {
printf('<tr><td colspan=3>%s</td></tr>',
_('Media SCRATCH Status'));
echo $temp;
echo '<tr><td>&nbsp;</td></tr>';
$temp = '';
}
# Media Access
foreach (array('FULL','FILLING','PENDING','EMPTY') as $status) {
if (count($volumes->getStoragePoolVolumesStatus($stgpool->getName(),$status)))
$temp .= sprintf('<tr><td>&nbsp;</td><td>'.
classValue(_('%s media %s.'),'value').
'</td><td>&nbsp;</td></tr>',
count($volumes->getStoragePoolVolumesStatus($stgpool->getName(),$status)),$status);
}
if ($temp) {
printf('<tr><td colspan=3>%s</td></tr>',
_('Media FILLING Status'));
echo $temp;
echo '<tr><td>&nbsp;</td></tr>';
$temp = '';
}
foreach (array('READWRITE','READONLY','UNAVAILABLE','OFFSITE','DESTROYED') as $status) {
if (count($volumes->getStoragePoolVolumesAccess($stgpool->getName(),$status)))
$temp .= sprintf('<tr><td>&nbsp;</td><td>'.
classValue(_('%s media %s.'),'value').
'</td><td>&nbsp;</td></tr>',
count($volumes->getStoragePoolVolumesAccess($stgpool->getName(),$status)),$status);
}
if ($temp) {
printf('<tr><td colspan=3>%s</td></tr>',
_('Media ACCESS Status'));
echo $temp;
echo '<tr><td>&nbsp;</td></tr>';
$temp = '';
}
# Utilisation
$stat['count'] = 0;
$stat['util'] = 0;
$stat['reclaim'] = 0;
$stat['cap'] = 0;
foreach ($volumes->getStoragePoolVolumes($stgpool->getName()) as $volume) {
$stat['util'] += $volume->utilisation;
$stat['reclaim'] += $volume->reclaim;
$stat['cap'] += $volume->estcap;
$stat['count']++;
}
if ($stat['count'] > 0) {
printf('<tr><td colspan=3>%s</td></tr>',
_('Media Stats'));
printf('<tr><td>&nbsp;</td><td>'.
classValue(_('%3.2f%% average utilisation.'),'value').
'</td><td>&nbsp;</td></tr>',
$stat['util']/$stat['count']);
printf('<tr><td>&nbsp;</td><td>'.
classValue(_('%3.2f%% average wasted space.'),'value').
'</td><td>&nbsp;</td></tr>',
$stat['reclaim']/$stat['count']);
printf('<tr><td>&nbsp;</td><td>'.
classValue(_('%3.0f MB average capacity.'),'value').
'</td><td>&nbsp;</td></tr>',
$stat['cap']/$stat['count']);
}
break;
}
echo '<tr><td>&nbsp;</td></tr>';
# Nodes with data in this pool
echo "\n\n";
$total = 0;
$nodedata = '';
$counter = 0;
foreach ($occupancy->getStoragePoolTotals($stgpool->getName()) as $node => $typedetails) {
$node = $nodes->getNode($node);
foreach ($typedetails as $type => $details) {
$nodedata .= sprintf('<tr class="%s"><td>%s</td><td>%s</td><td align="right">%s %s</td><td align="right">%s MB</td></tr>',
($counter++%2==0?'even':'odd'),
$node->getName(),$type,
(isset($detail['files']) ? number_format($detail['files']) : '&nbsp;'),
(count($node->getTapeVolumes($stgpool->getName(),$type)) ? count($node->getTapeVolumes($stgpool->getName(),$type)) : '&nbsp;'),
isset($details['physical']) ? number_format($details['physical']) : '&nbsp;');
$total += $details['physical'];
}
}
if ($nodedata) {
echo '<tr><td colspan=2>'."\n\n";
echo '<table class="result_table" border=0>';
printf('<tr><td colspan=4 class="heading">%s</td></tr>',
_('Nodes with data in this storage pool.'));
printf('<tr class="title"><td class="titlel">%s</td><td class="titler">%s</td><td class="titler">%s</td><td class="titler">%s</td></tr>',
_('Node'),_('Type'),_('Volumes'),_('MB'));
echo $nodedata;
printf('<tr class="highlight"><td colspan=3 class="titlel">%s</td><td class="titler">%s MB</td></tr>',
_('Total'),number_format($total));
echo '</table>'."\n\n";
echo '</td><td>&nbsp;</td></tr>';
echo '<tr><td>&nbsp;</td></tr>';
}
echo '</table><br />'."\n\n";
}
if (! $stgcount)
printf('<b>%s</b><br />',_('There are no storage pools using this DEVCLASS.'));
}
?>

116
htdocs/gantt.activity.php Normal file
View File

@ -0,0 +1,116 @@
<?php
// $Header: /cvsroot/phptsmadmin/phpTSMadmin/htdocs/gantt.activity.php,v 1.6 2008/07/01 01:18:34 wurley Exp $
# Required Libraries
require './common.php';
initJPGraph(true);
# Defaults
$reportEnd = strftime('%y-%m-%d %H:%M',time());
$reportStart = strftime('%y-%m-%d %H:%M',time()-86400);
$startActivities['811'] = array('start'=>'Expire Inventory');
$startActivities['812'] = array('success'=>'Expire Inventory');
$startActivities['2562'] = array('start'=>'Event Records Delete');
$startActivities['2564'] = array('success'=>'Event Records Delete');
$startActivities['2102'] = array('start'=>'Activity Log Delete');
$startActivities['2102'] = array('success'=>'Activity Log Delete');
$startActivities['2280'] = array('start'=>'DB Backup');
$startActivities['4550'] = array('success'=>'DB Backup');
$startActivities['406'] = array('start'=>'Session');
$startActivities['403'] = array('success'=>'Session');
# Admin schedules
$tsmActivitys = TSMQuery($_REQUEST['server_id'],"select date(DATE_TIME) as DATE,time(DATE_TIME) as TIME,MSGNO from ACTLOG where ORIGINATOR='SERVER' and DATE_TIME \> '$reportStart' and MSGNO in (".implode(",",array_keys($startActivities)).")");
foreach ($tsmActivitys as $tsmActivity) {
$datetime = $tsmActivity['DATE']." ".(preg_replace('/(.*:.*):.*/',"$1",$tsmActivity['TIME']));
$msgNum = $tsmActivity['MSGNO'];
# Do we know this message number?
if (isset($startActivities[$msgNum])) {
# New Event.
if (isset($startActivities[$msgNum]['start'])) {
$activity[$startActivities[$msgNum]['start']][]['start'] = $datetime;
} else if (isset($startActivities[$msgNum]['success'])) {
$item = (isset($activity[$startActivities[$msgNum]['success']]) ?
count($activity[$startActivities[$msgNum]['success']])-1 : 0);
# Is there a start event.
if (! isset($activity[$startActivities[$msgNum]['success']][$item]['start'])) {
$activity[$startActivities[$msgNum]['success']][$item]['start'] = $datetime;
}
$activity[$startActivities[$msgNum]['success']][$item]['end'] = $datetime;
} else {
print "Che? Unknown index??";
}
} else {
}
}
// A new graph with automatic size
$graph = new GanttGraph(0,0,"auto");
$item = 0;
# Admin Schedules
foreach ($activity as $tsmSchedAdmin => $value) {
foreach ($value as $instance) {
printf ("Drawing [%s] [%s] [%s] [%s]<BR>",$item,$tsmSchedAdmin,$instance['start'],($instance['end'] ? $instance['end'] : $instance['start']));
$activity = new GanttBar($item,$tsmSchedAdmin,$instance['start'],($instance['end'] ? $instance['end'] : $instance['start']));
$item++;
$graph->Add($activity);
}
}
$graph->SetMarginColor('white');
$graph->SetFrame(false);
// We want to display day, hour and minute scales
$graph->ShowHeaders(GANTT_HDAY | GANTT_HHOUR | GANTT_HMIN);
$graph->hgrid->Show();
$graph->hgrid->SetRowFillColor('darkred@0.85');
$graph->hgrid->line->SetColor('red@0.85');
$graph->hgrid->line->Show(false);
// A new activity on row '0'
// Setup hour format
$graph->scale->hour->SetIntervall(1);
$graph->scale->hour->SetStyle(HOURSTYLE_H24);
$graph->scale->minute->SetIntervall(30);
// Display the Gantt chart
$graph->Stroke();
die();
# Block Title
$blockTitle = _('Server Status for').'&nbsp;'.TSMServerName($_REQUEST['server_id']);
$blockBody = '<table border="0" cellpadding="0" cellspacing="0" class="blockcitem">';
# Client Details
$blockBody .= '<tr><th colspan=2 class="title">&nbsp;Clients</th><th class="title">&nbsp;</th></tr>';
#$blockBody .= sprintf('<tr><td>&nbsp;</td><td>'.
# classValue(_('%s clients registered to this TSM server.'),'value').
# '</td><td>&nbsp;</td></tr>',
# count($tsmClientsTotal));
$blockBody .= '<tr><td colspan=3>&nbsp;</td></tr>';
# End
$blockBody .= '</table>';
$left = ''; # Use default left blocks.
$centre = buildBlock("centre",$blockTitle,$blockBody);
$right = ''; # Use default right blocks.
print buildPage($left,$centre,$right);
?>

70
htdocs/help.php Normal file
View File

@ -0,0 +1,70 @@
<?php
// $Header: /cvsroot/phptsmadmin/phpTSMadmin/htdocs/help.php,v 1.3 2009/04/19 03:53:40 wurley Exp $
# This page should detail on Client storage usage.
# Required Libraries
require './common.php';
# Defaults
$help = objectCache('help');
$form['command'] = get_request('command','REQUEST');
# List of Clients.
$blockTitle['help'] = sprintf(_('Select HELP on %s'),$app['server']->getValue('server','name'));
$blockBody['help'] = '<form action="cmd.php">';
$blockBody['help'] .= sprintf('<input type="hidden" name="cmd" value="%s" />',get_request('cmd','REQUEST'));
$blockBody['help'] .= '<table class="blockcitem">';
$blockBody['help'] .= '<tr><td width=0%>';
$blockBody['help'] .= sprintf('<input type="hidden" name="index" value="%s" />',$app['server']->getIndex());
$blockBody['help'] .= '<select name="command">';
foreach ($help->getCommands() as $command) {
$blockBody['help'] .= sprintf('<option id="%s" %s>%s</option>',
$command,
isset($form['command']) && $command == $form['command'] ? 'selected' : '',
$command);
}
$blockBody['help'] .= '</select>';
$blockBody['help'] .= '</td>';
$blockBody['help'] .= '<td><input type="checkbox" name="raw" title="Show RAW help page"/></td>';
$blockBody['help'] .= '<td><input align="left" type="submit" name="submit" value="Go" /></td>';
$blockBody['help'] .= '<td width=100%>&nbsp;</td>';
$blockBody['help'] .= '</tr>';
$blockBody['help'] .= '</table>';
$blockBody['help'] .= '</form>';
if (isset($form['command'])) {
$helpCommand = $help->getCommand($form['command']);
if (get_request('raw','REQUEST')) {
$blockBody['help'] .= '<pre>'.implode('<br />',$helpCommand->raw).'</pre>';
} else {
$blockBody['help'] .= '<br />';
$blockBody['help'] .= '<table class="blockcitem">';
$blockBody['help'] .= sprintf('<tr><td><h3><u>%s</u></h3></td></tr>',$helpCommand->getTitle());
$blockBody['help'] .= sprintf('<tr><td>%s</td></tr>',$helpCommand->getDescription());
$blockBody['help'] .= sprintf('<tr><td><b>%s</b></td></tr>',_('Privileges Required'));
$blockBody['help'] .= sprintf('<tr><td>%s</td></tr>',$helpCommand->getClass());
$blockBody['help'] .= sprintf('<tr><td><b>%s</b></td></tr>',_('Syntax'));
$blockBody['help'] .= sprintf('<tr><td>%s</td></tr>',$helpCommand->getSyntax());
$blockBody['help'] .= sprintf('<tr><td><b>%s</b></td></tr>',_('Parameters'));
$blockBody['help'] .= sprintf('<tr><td>%s</td></tr>',$helpCommand->getParameters());
$blockBody['help'] .= '<tr><td>&nbsp;</td></tr>';
$blockBody['help'] .= sprintf('<tr><td><b>%s</b></td></tr>',_('Related Commands'));
$blockBody['help'] .= sprintf('<tr><td>%s</td></tr>',$helpCommand->getRelated());
$blockBody['help'] .= '</table>';
}
}
# End
render_page($blockTitle,$blockBody);
?>

View File

@ -0,0 +1,57 @@
<?php
// $Header: /cvsroot/phptsmadmin/phpTSMadmin/htdocs/image.backupevents.php,v 1.6 2009/04/19 03:53:40 wurley Exp $
# Required Libraries
require './common.php';
initJPGraph(true);
if (! isset($_SESSION['graph']['backupevent']))
exit;
# Make sure all our keys for each sched are the same.
foreach ($_SESSION['graph']['backupevent']['data'] as $sched => $details) {
foreach ($_SESSION['graph']['backupevent']['legend'] as $key => $count) {
@$_SESSION['graph']['backupevent']['data'][$sched][$key] += 0;
}
ksort($_SESSION['graph']['backupevent']['data'][$sched]);
}
$graph_row = 2;
$xcounter = 1;
$ycounter = 1;
$numrows = round(count($_SESSION['graph']['backupevent']['data'])/$graph_row);
$graph = new PieGraph(500,30+180*$numrows,'auto');
foreach ($_SESSION['graph']['backupevent']['data'] as $sched => $details) {
ksort($details);
$newsched = preg_replace('/-/','_',$sched);
$$newsched = new PiePlot(array_values($details));
$$newsched->SetCenter(120+(($xcounter%$graph_row)*160),120+(($ycounter-1)*180));
$$newsched->SetGuideLines(false,false);
$$newsched->SetGuideLinesAdjust(1.0);
$$newsched->SetSize(60);
$$newsched->SetTheme('sand');
$$newsched->value->SetFormat('%2.1f%%');
$$newsched->title->Set($sched);
$$newsched->title->SetMargin(10);
if ($xcounter == 1)
$$newsched->SetLegends(array_keys($details));
$graph->Add($$newsched);
if (! ($xcounter%$graph_row))
$ycounter++;
$xcounter++;
}
$graph->legend->SetFillColor('azure');
$graph->SetMarginColor('azure2');
$graph->title->Set(sprintf('Schedule Backup Status for %s',$app['server']->GetStatusDetail('SERVER_NAME')));
# Display the chart
unset($_SESSION['graph']['backupevent']);
$graph->Stroke();
?>

View File

@ -0,0 +1,83 @@
<?php
// $Header: /cvsroot/phptsmadmin/phpTSMadmin/htdocs/image.dbbackuphistory.php,v 1.7 2009/04/19 03:54:40 wurley Exp $
# Required Libraries
require './common.php';
initJPGraph(true);
$history = $app['server']->GetDBBackupDetail('history');
if (! $history)
exit;
$graph = new Graph(400,200,'auto');
$graph->SetScale('textlin');
$fulldata = array();
$incrdata = array();
$xtitles = array();
foreach ($app['server']->GetDBBackupDetail('history') as $index => $backupdetails) {
switch ($backupdetails['type']) {
case 'FULL' :
$fulldata[] = $backupdetails['size'];
$incrdata[] = 0;
break;
case 'INCR' :
$fulldata[] = 0;
$incrdata[] = $backupdetails['size'];
break;
}
$xtitles[] = preg_replace('/ /',"\n",tsmDate($backupdetails['date'],'daytime'));
$maxdata[] = $app['server']->GetDBDetail('USABLE_PAGES');
$curdata[] = $app['server']->GetDBDetail('USED_PAGES');
}
$cplot = new LinePlot($maxdata);
$cplot->SetLegend('Max DB Size');
$cplot->SetColor('red');
$cplot->SetWeight(2);
if (count($maxdata) == 1)
$cplot->mark->SetType(MARK_IMG_MBALL,'red',0.5);
$graph->Add($cplot);
$dplot = new LinePlot($curdata);
$dplot->SetLegend('Cur Size');
$dplot->SetColor('lightred');
$dplot->SetWeight(2);
$graph->Add($dplot);
$aplot = new BarPlot($fulldata);
$aplot->SetLegend('Full');
$aplot->SetFillColor('blue');
$aplot->value->Show();
$aplot->value->SetFormat('%5.0f');
$graph->Add($aplot);
$bplot = new BarPlot($incrdata);
$bplot->SetLegend('Incremental');
$bplot->SetFillColor('lightblue');
$bplot->value->Show();
$bplot->value->SetFormat('%5.0f');
$graph->Add($bplot);
$graph->img->SetMargin(60,110,20,40);
$graph->legend->Pos(0.01,0.80,'right','center');
$graph->legend->SetFillColor('azure');
$graph->xaxis->SetTickLabels($xtitles);
$graph->xaxis->SetLabelAngle(90);
$graph->xgrid->Show(true);
$graph->yaxis->title->Set('Database Pages \'000s');
$graph->yaxis->SetLabelFormatCallback('labelformat');
$graph->yaxis->SetTitleMargin(45);
$graph->SetMarginColor('azure2');
$graph->title->Set(sprintf('Database Backups %s',$app['server']->GetStatusDetail('SERVER_NAME')));
# Display the Gantt chart
$graph->Stroke();
function labelformat($label) {
return number_format($label/1000);
}
?>

View File

@ -0,0 +1,37 @@
<?php
// $Header: /cvsroot/phptsmadmin/phpTSMadmin/htdocs/image.occupancy.php,v 1.8 2009/04/19 03:54:40 wurley Exp $
# Required Libraries
require './common.php';
initJPGraph(true);
if (! isset($_SESSION['graph']['occupancy']))
exit;
ksort($_SESSION['graph']['occupancy']);
$num = count($_SESSION['graph']['occupancy'])-10;
if ($num < 0)
$num = 0;
$graph = new PieGraph(400,200+20*$num,'auto');
$plot = new PiePlot(array_values($_SESSION['graph']['occupancy']));
$plot->SetLegends(array_keys($_SESSION['graph']['occupancy']));
# It seems the guide lines break the grpah if there are large number of points.
//$plot->SetGuideLines(false,false);
//$plot->SetGuideLinesAdjust(1.0);
$plot->value->SetFormat('%2.1f%%');
$plot->SetCenter(200,100);
$plot->SetSize(60);
$plot->SetTheme('sand');
$graph->Add($plot);
$graph->legend->SetFillColor('azure');
$graph->SetMarginColor('azure2');
$graph->title->Set(sprintf('Storage Used by Last Access for %s',$app['server']->GetStatusDetail('SERVER_NAME')));
# Display the chart
unset($_SESSION['graph']['occupancy']);
$graph->Stroke();
?>

View File

@ -0,0 +1,88 @@
<?php
// $Header: /cvsroot/phptsmadmin/phpTSMadmin/htdocs/image.schedule.gantt.php,v 1.2 2009/04/19 03:54:40 wurley Exp $
# TODO:
# Need better date handling - currently this script misses out events that start before midnight, but flow into today.
# Want to make a week/month view, or select the day to view.
# Currently only DURUNITS of HOUR schedules are shown.
# Currently ASSUMES PERUNITS of DAY.
# Required Libraries
require './common.php';
initJPGraph(true);
# Defaults
# Get Schedules
$dayOfWeek = strtoupper(strftime('%A',time()));
$todayDate = strftime('%y-%m-%d',time());
$tsmSchedAdmins = $app['server']->query("select * from ADMIN_SCHEDULES where DAYOFWEEK in ('ANY','".$dayOfWeek."')",null,'SCHEDULE_NAME');
$tsmSchedClients = $app['server']->query("select * from CLIENT_SCHEDULES where DAYOFWEEK in ('ANY','".$dayOfWeek."')",null,'SCHEDULE_NAME');
# A new graph with automatic size
$graph = new GanttGraph(0,0,"auto");
# Only show the current date.
$graph->SetDateRange($todayDate,$todayDate);
$graph->SetMarginColor('#eeeeff');
$graph->SetFrame(true,'#eeeeff',0);
# We want to display day, hour and minute scales
$graph->ShowHeaders(GANTT_HDAY | GANTT_HHOUR | GANTT_HMIN);
# Setup hour format
$graph->scale->hour->SetIntervall(1);
$graph->scale->hour->SetStyle(HOURSTYLE_H24);
$graph->scale->minute->SetIntervall(30);
$graph->hgrid->Show();
$graph->hgrid->SetRowFillColor('darkred@0.85');
$item = 0;
# Admin Schedules
if ($tsmSchedAdmins) {
foreach ($tsmSchedAdmins as $tsmSchedAdmin) {
if ($tsmSchedAdmin['DURUNITS'] == 'HOURS') {
$activity = new GanttBar($item,$tsmSchedAdmin['SCHEDULE_NAME'].
($tsmSchedAdmin['DESCRIPTION'] ? ' ('.$tsmSchedAdmin['DESCRIPTION'].')' : null),
strftime('%Y-%m-%d',time()).' '.$tsmSchedAdmin['STARTTIME'],
$tsmSchedAdmin['DURATION']/24);
if ($tsmSchedAdmin['ACTIVE'] == "NO") {
$activity->SetColor('gray');
$activity->SetPattern(GANTT_SOLID,'gray',50);
}
$item++;
$graph->Add($activity);
}
}
}
$item++;
# ClientSchedules
if ($tsmSchedClients) {
foreach ($tsmSchedClients as $tsmSchedAdmin) {
if ($tsmSchedAdmin['DURUNITS'] == 'HOURS') {
$activity = new GanttBar($item,$tsmSchedAdmin['SCHEDULE_NAME'].
($tsmSchedAdmin['DESCRIPTION'] ? ' ('.$tsmSchedAdmin['DESCRIPTION'].')' : null),
strftime('%Y-%m-%d',time()).' '.$tsmSchedAdmin['STARTTIME'],
$tsmSchedAdmin['DURATION']/24);
$item++;
$graph->Add($activity);
}
}
}
# Show the current time.
$vline = new GanttVLine (strftime('%Y-%m-%d %H:%M',time()),"", "darkred",5);
$graph->Add($vline);
# Display the Gantt chart
$graph->Stroke();
?>

View File

@ -0,0 +1,62 @@
<?php
// $Header: /cvsroot/phptsmadmin/phpTSMadmin/htdocs/image.server.stats.php,v 1.6 2009/04/19 03:54:40 wurley Exp $
# Required Libraries
require './common.php';
initJPGraph(true);
$activity = $_REQUEST['activity'];
if (! isset($_SESSION['graph'][$activity]))
exit;
$color_array = array(
'darkred','aquamarine','blue','violet','blueviolet','red','brown','burlywood','cadetblue','chocolate','red','darkred');
$graph = new Graph(900,300,'auto');
$graph->SetScale('datlin',0,(isset($_SESSION['graph'][$activity]['mode']) ? $_SESSION['graph'][$activity]['mode']*2 : 0));
ksort($_SESSION['graph'][$activity]['data']);
$counter = 0;
foreach ($_SESSION['graph'][$activity]['data'] as $process => $detail) {
$color = $counter%count($color_array);
$$process = new LinePlot(array_values($detail),array_keys($detail));
$$process->SetLegend($process);
$$process->SetColor($color_array[$color]);
$$process->mark->SetType(MARK_IMG_MBALL,$color,0.3);
$graph->Add($$process);
$counter++;
}
$graph->xaxis->SetLabelAngle(90);
$graph->img->SetMargin(60,160,20,80);
$graph->legend->Pos(0.01,0.50,'right','center');
$graph->legend->SetFillColor('azure');
$graph->yaxis->SetLabelFormatCallback('labelformat');
$graph->yaxis->SetTitleMargin(45);
$graph->SetMarginColor('azure2');
switch($activity) {
case 'mediawait' :
$graph->yaxis->title->Set('Wait Time (mins)');
$graph->title->Set(sprintf('Media Wait Time %s',$app['server']->GetStatusDetail('SERVER_NAME')));
break;
case 'thruput' :
$graph->yaxis->title->Set('Thruput (MB/s)');
$graph->title->Set(sprintf('Data Thruput %s',$app['server']->GetStatusDetail('SERVER_NAME')));
break;
default :
$graph->yaxis->title->Set('Unknown');
$graph->title->Set(sprintf('Unknown Report %s',$app['server']->GetStatusDetail('SERVER_NAME')));
}
# Display the chart
$graph->Stroke();
unset($_SESSION['graph'][$activity]);
function labelformat($label) {
return sprintf('%3.1f',$label/60);
}
?>

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 648 B

BIN
htdocs/images/error.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

BIN
htdocs/images/favicon.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

BIN
htdocs/images/home-big.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

55
htdocs/images/index.php Normal file
View File

@ -0,0 +1,55 @@
<?php
// $Header: /cvsroot/phptsmadmin/phpTSMadmin/htdocs/images/index.php,v 1.1 2008/01/15 10:15:28 wurley Exp $
/**
* This will show a nice table of all the icons used by this application.
*
* @package leenooksApp
*/
echo '<html>';
echo '<title>Application Icons</title>';
echo '<head><link type="text/css" rel="stylesheet" href="../css/style.css" media="screen" /></head>';
echo '<body>';
echo '<h3 class="title">Application Icons</h3>';
echo '<br />';
echo '<center>';
$dir = opendir('.');
while (($file = readdir($dir)) !== false) {
if ($file == '.' || $file == '..')
continue;
if (! preg_match('/\.png$/',$file))
continue;
$files[filesize($file).'_'.$file] = $file;
}
sort($files);
$cell_style = 'color: #888; text-align:center; padding: 10px; padding-bottom: 20px; vertical-align: bottom;';
printf('<center><b>The %s icons used by this application.</b></center>',count($files));
echo '<table style="font-family: arial; font-size: 12px;">';
$counter = 0;
foreach ($files as $file) {
if ($counter % 6 == 0) {
if ($counter)
echo '</tr>'."\n";
flush();
echo '<tr>';
}
$counter++;
printf('<td style="%s"><img title="%s" src="%s" /><br />%s</td>',$cell_style,htmlspecialchars($file),htmlspecialchars($file),$file);
}
echo '</tr>';
echo '</table>';
echo '</center>';
echo '</body>';
echo '</html>';
?>

BIN
htdocs/images/info.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 733 B

BIN
htdocs/images/key.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 519 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

BIN
htdocs/images/logout.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 829 B

BIN
htdocs/images/minus.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 98 B

BIN
htdocs/images/plus.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 102 B

BIN
htdocs/images/server.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

BIN
htdocs/images/timeout.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 608 B

BIN
htdocs/images/trash-big.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

BIN
htdocs/images/uid.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 654 B

BIN
htdocs/images/warning.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

133
htdocs/index.php Normal file
View File

@ -0,0 +1,133 @@
<?php
// $Header: /cvsroot/phptsmadmin/phpTSMadmin/htdocs/index.php,v 1.13 2009/04/19 03:55:24 wurley Exp $
/**
* Application Start Page
*
* @package phpTSMadmin
* @subpackage Page
*/
/**
* @package leenooksApp
*/
/*******************************************
<pre>
If you are seeing this in your browser,
PHP is not installed on your web server!!!
</pre>
*******************************************/
/**
* We will perform some sanity checking here, since this file is normally loaded first when users
* first access the application.
*/
# The index we will store our config in $_SESSION
define('APPCONFIG','appConfig');
define('LIBDIR',sprintf('%s/',realpath('../lib/')));
ini_set('display_errors',1);
error_reporting(E_ALL);
# General functions needed to proceed.
ob_start();
if (! file_exists(LIBDIR.'functions.php')) {
if (ob_get_level()) ob_end_clean();
die(sprintf("Fatal error: Required file '<b>%sfunctions.php</b>' does not exist.",LIBDIR));
}
if (! is_readable(LIBDIR.'functions.php')) {
if (ob_get_level()) ob_end_clean();
die(sprintf("Cannot read the file '<b>%sfunctions.php</b>' its permissions may be too strict.",LIBDIR));
}
if (ob_get_level())
ob_end_clean();
# Make sure this PHP install has pcre
if (! extension_loaded('pcre'))
die('<p>Your install of PHP appears to be missing PCRE support.</p><p>Please install PCRE support before using this application.<br /><small>(Dont forget to restart your web server afterwards)</small></p>');
require LIBDIR.'functions.php';
# Define the path to our configuration file.
if (defined('CONFDIR'))
$app['config_file'] = CONFDIR.'config.php';
else
$app['config_file'] = 'config.php';
# Make sure this PHP install has session support
if (! extension_loaded('session'))
error('<p>Your install of PHP appears to be missing php-session support.</p><p>Please install php-session support before using this application.<br /><small>(Dont forget to restart your web server afterwards)</small></p>','error',null,true);
# Make sure this PHP install has gettext, we use it for language translation
if (! extension_loaded('gettext'))
system_message(array(
'title'=>_('Missing required extension'),
'body'=>'Your install of PHP appears to be missing GETTEXT support.</p><p>GETTEXT is used for language translation.</p><p>Please install GETTEXT support before using this application.<br /><small>(Dont forget to restart your web server afterwards)</small>',
'type'=>'error'));
# Make sure this PHP install has all our required extensions
/**
* Helper functions.
* Our required helper functions are defined in functions.php
*/
if (isset($app['function_files']) && is_array($app['function_files']))
foreach ($app['function_files'] as $file_name ) {
if (! file_exists($file_name))
error(sprintf('Fatal error: Required file "%s" does not exist.',$file_name),'error',null,true);
if (! is_readable($file_name))
error(sprintf('Fatal error: Cannot read the file "%s", its permissions may be too strict.',$file_name),'error',null,true);
ob_start();
require $file_name;
if (ob_get_level()) ob_end_clean();
}
# Configuration File check
if (! file_exists($app['config_file'])) {
error(sprintf(_('You need to configure %s. Edit the file "%s" to do so. An example config file is provided in "%s.example".'),app_name(),$app['config_file'],$app['config_file']),'error',null,true);
} elseif (! is_readable($app['config_file'])) {
error(sprintf('Fatal error: Cannot read your configuration file "%s", its permissions may be too strict.',$app['config_file']),'error',null,true);
}
# If our config file fails the sanity check, then stop now.
if (! $config = check_config($app['config_file'])) {
$www['page'] = new page();
$www['body'] = new block();
$www['page']->block_add('body',$www['body']);
$www['page']->display();
exit;
} else {
app_session_start();
$_SESSION[APPCONFIG] = $config;
}
if ($uri = get_request('URI','GET'))
header(sprintf('Location: cmd.php?%s',base64_decode($uri)));
if (! ereg('^([0-9]+\.?)+',app_version())) {
if (count($_SESSION[APPCONFIG]->untested()))
system_message(array(
'title'=>'Untested configuration paramaters',
'body'=>sprintf('The following parameters have not been tested. If you have configured these parameters, and they are working as expected, please let the developers know, so that they can be removed from this message.<br/><small>%s</small>',join(', ',$_SESSION[APPCONFIG]->untested())),
'type'=>'info','special'=>true));
$server = $_SESSION[APPCONFIG]->getServer(get_request('server_id','REQUEST'));
if (count($server->untested()))
system_message(array(
'title'=>'Untested server configuration paramaters',
'body'=>sprintf('The following parameters have not been tested. If you have configured these parameters, and they are working as expected, please let the developers know, so that they can be removed from this message.<br/><small>%s</small>',join(', ',$server->untested())),
'type'=>'info','special'=>true));
}
include './cmd.php';
?>

111
htdocs/js/app_ajax.js Normal file
View File

@ -0,0 +1,111 @@
// $Header: /cvsroot/phptsmadmin/phpTSMadmin/htdocs/js/app_ajax.js,v 1.1 2008/01/14 22:13:26 wurley Exp $
/**
* @package leenooksApp
*/
// current request
var http_request = null;
var http_request_success_callback = '';
var http_request_error_callback = '';
// include html into a component
function includeHTML(component, html) {
if (typeof(component) != 'object' || typeof(html) != 'string') return;
component.innerHTML = html;
var scripts = component.getElementsByTagName('script');
if (!scripts) return;
// load scripts
for (var i = 0; i < scripts.length; i++) {
var scriptclone = document.createElement('script');
if (scripts[i].attributes.length > 0) {
for (var j in scripts[i].attributes) {
if (typeof(scripts[i].attributes[j]) != 'undefined'
&& typeof(scripts[i].attributes[j].nodeName) != 'undefined'
&& scripts[i].attributes[j].nodeValue != null
&& scripts[i].attributes[j].nodeValue != '') {
scriptclone.setAttribute(scripts[i].attributes[j].nodeName, scripts[i].attributes[j].nodeValue);
}
}
}
scriptclone.text = scripts[i].text;
scripts[i].parentNode.replaceChild(scriptclone, scripts[i]);
eval(scripts[i].innerHTML);
}
}
// callback function
function alertHttpRequest() {
if (http_request && (http_request.readyState == 4)) {
if (http_request.status == 200) {
response = http_request.responseText;
http_request = null;
//alert(response);
if (http_request_success_callback) {
eval(http_request_success_callback + '(response)');
}
} else {
alert('There was a problem with the request.');
cancelHttpRequest();
}
}
}
function cancelHttpRequest() {
if (http_request) {
http_request = null;
if (http_request_error_callback) {
eval(http_request_error_callback + '()');
}
}
}
// resquest
function makeGETRequest(url, parameters, successCallbackFunctionName, errorCallbackFunctionName) {
makeHttpRequest(url, parameters, 'GET', successCallbackFunctionName, errorCallbackFunctionName);
}
function makePOSTRequest(url, parameters, successCallbackFunctionName, errorCallbackFunctionName) {
makeHttpRequest(url, parameters, 'POST', successCallbackFunctionName, errorCallbackFunctionName);
}
function makeHttpRequest(url, parameters, meth, successCallbackFunctionName, errorCallbackFunctionName) {
cancelHttpRequest();
http_request_success_callback = successCallbackFunctionName;
http_request_error_callback = errorCallbackFunctionName;
if (window.XMLHttpRequest) { // Mozilla, Safari,...
http_request = new XMLHttpRequest();
if (http_request.overrideMimeType) {
http_request.overrideMimeType('text/html');
}
} else if (window.ActiveXObject) { // IE
try {
http_request = new ActiveXObject("Msxml2.XMLHTTP");
} catch (e) {
try {
http_request = new ActiveXObject("Microsoft.XMLHTTP");
} catch (e) {}
}
}
if (!http_request) {
alert('Cannot create XMLHTTP instance.');
return false;
}
http_request.onreadystatechange = window['alertHttpRequest'];
if (meth == 'GET') url = url + '?' + parameters;
http_request.open(meth, url, true);
http_request.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
http_request.setRequestHeader("Content-length", parameters.length);
http_request.setRequestHeader("Connection", "close");
if (meth == 'GET') parameters = null;
http_request.send(parameters);
}

18
htdocs/js/menu_hide.js Normal file
View File

@ -0,0 +1,18 @@
var current;
/**
* Toggle the displayed menu
*/
function menu_unhide(whichLayer,old) {
if (current == null) current = old;
var oldmenu = document.getElementById('MID_'+current).style;
oldmenu.display = 'none';
if (document.getElementById) {
// this is the way the standards work
var newmenu = document.getElementById(whichLayer).value;
var newmenu_div = document.getElementById('MID_'+newmenu).style;
newmenu_div.display = 'block';
}
current = newmenu;
}

166
htdocs/library.info.php Normal file
View File

@ -0,0 +1,166 @@
<?php
// $Header: /cvsroot/phptsmadmin/phpTSMadmin/htdocs/library.info.php,v 1.21 2008/08/14 06:44:39 wurley Exp $
# @todo: It would be nice, if show slots hasnt been run, that we display a message to run audit libr. Then we will know that slots are empty, and be able to show that correctly.
# Required Libraries
require './common.php';
# Data collection.
$libraries = objectCache('libraries');
$volumes = objectCache('volumes');
$stgpools = objectCache('stgps');
# Library
if ($libraries->getLibraries()) {
foreach ($libraries->getLibraries() as $library) {
printf(_('Information on libraries %s.'),$library->getName());
echo '<table width="100%" class="result" border=0>';
# Does this library support show slots?
if (isset($library->slots)) {
printf('<tr><td colspan=3>'.
classValue(_('This is a %s library, with %s slots and %s drives.'),'value').
'</td><td>&nbsp;</td></tr>',
$library->getAttr('ProductId'),
$library->getAttr('Slots'),
$library->getAttr('Drives'));
# Show the drives
foreach ($library->getDrives() as $drive) {
printf('<tr><td>&nbsp;</td><td colspan=2>'.
classValue(_('Drive %s (Status %s).'),'value').
'</td><td>&nbsp;</td></tr>',
$drive->getName(),
$drive->volume ? sprintf('%s-%s',$drive->status,$drive->volume) : $drive->status);
}
echo '<tr><td colspan=3>&nbsp;</td></tr>';
# Library Configuration
printf('<tr><td>&nbsp;</td><td colspan=2>'.
classValue(_('%s shared library.'),'value').
'</td><td>&nbsp;</td></tr>',
$library->shared);
printf('<tr><td>&nbsp;</td><td colspan=2>'.
classValue(_('%s auto label.'),'value').
'</td><td>&nbsp;</td></tr>',
($library->autolabel ? $library->autolabel : 'NO'));
# Volume Details
printf('<tr><td>&nbsp;</td><td colspan=2>'.
classValue(_('%s slots with NO volumes.'),'value').
'</td><td>&nbsp;</td></tr>',
$library->getAttr('Slots') - count($library->slots));
printf('<tr><td>&nbsp;</td><td colspan=2>'.
classValue(_('%s volumes physically in this library.'),'value').
'</td><td>&nbsp;</td></tr>',
count($library->slotVolumes(true))+count($library->slotVolumes(false)));
printf('<tr><td>&nbsp;</td><td colspan=2>'.
classValue(_('%s volumes NOT checked in.'),'value').
'</td><td>&nbsp;</td></tr>',
count($library->slotVolumes(false)));
printf('<tr><td>&nbsp;</td><td colspan=2>'.
classValue(_('%s volumes are checked into this library.'),'value').
'</td><td>&nbsp;</td></tr>',
count($library->slotVolumes(true)));
printf('<tr><td>&nbsp;</td><td>&nbsp;</td><td>'.
classValue(_('%s EMPTY volumes.'),'value').
'</td><td>&nbsp;</td></tr>',
count($library->getLibraryEmpty()));
printf('<tr><td>&nbsp;</td><td>&nbsp;</td><td>'.
classValue(_('%s PENDING volumes.'),'value').
'</td><td>&nbsp;</td></tr>',
count($library->getLibraryPending()));
printf('<tr><td>&nbsp;</td><td>&nbsp;</td><td>'.
classValue(_('%s SCRATCH volumes.'),'value').
'</td><td>&nbsp;</td></tr>',
count($library->getLibraryScratch()));
echo '<tr><td colspan=4>&nbsp;</td></tr>';
# Volumes in Library.
printf('<tr><td colspan=3>%s</td></tr>',
_('The following volumes are currently in this library:'));
echo '<tr><td colspan=3><table width="100%" class="result_table" border=0>';
echo '<tr><td class="heading">Slot</td><td class="heading">Barcode/Vol Name</td><td class="heading">Usage</td><td class="heading">Status/Access</td><td class="heading">Library Access</td><td class="heading">Utilisation</td><td class="heading">Reclaim</td><td class="heading">Last Read</td><td class="heading">Last Write</td></tr>';
foreach ($library->slots as $slotnum => $slot) {
if (isset($slot['barcodelabel']) && strlen($slot['barcodelabel']))
$volname = $slot['barcodelabel'];
elseif ($volumes->inElement($library->getName(),$slotnum))
$volname = $volumes->inElement($library->getName(),$slotnum);
else
$volname = 'No Barcode Label';
if ($volname && isset($volumes->volumes[$volname]->status['library']) && $volumes->volumes[$volname]->status['library'] == 'Scratch')
echo '<tr class="highlight">';
elseif ($slot['status'] == 'Full')
echo '<tr class="shadow">';
else
echo '<tr class="'.(@$counter++%2==0?'even':'odd').'">';
printf('<td><acronym title="Element: %s">%s</acronym></td><td>%s</td><td>%s</td><td>%s</td><td>%s</td><td>%s</td><td><acronym title="Storage Pool Reclaim: %s">%s</acronym></td><td>%s</td><td>%s</td></tr>',
$slotnum,
$slot['slot'],
$volname,
isset($volumes->volumes[$volname]->stgpool) ? $volumes->volumes[$volname]->stgpool :
(isset($volumes->volumes[$volname]->dbv['type']) ? $volumes->volumes[$volname]->dbv['type'] : '&nbsp;'),
isset($volumes->volumes[$volname]->status['volume']) ? sprintf('%s/%s',$volumes->volumes[$volname]->status['volume'],$volumes->volumes[$volname]->access) :
(isset($volumes->volumes[$volname]->dbv) ?
sprintf('%s.%s.%s',$volumes->volumes[$volname]->dbv['series'],
$volumes->volumes[$volname]->dbv['operation'],$volumes->volumes[$volname]->dbv['sequence']) : '&nbsp;'),
(isset($library->slots[$slotnum]['status']) && $library->slots[$slotnum]['status'] == 'Allocated') ?
isset($volumes->volumes[$volname]->status['library']) ? $volumes->volumes[$volname]->status['library'].'/'.$volumes->volumes[$volname]->lib['owner'] : '&nbsp;' :
_('*NOT CHECKED IN*'),
(isset($volumes->volumes[$volname]->status['volume']) && $volumes->volumes[$volname]->status['volume'] == 'PENDING') ?
tsmDate($volumes->volumes[$volname]->pending['start'],'notime') :
isset($volumes->volumes[$volname]->utilisation) ? $volumes->volumes[$volname]->utilisation.'%' : '&nbsp;',
isset($volumes->volumes[$volname]->stgpool) ? $stgpools->getReclaim($volumes->volumes[$volname]->stgpool).'%' : 'N/A',
isset($volumes->volumes[$volname]->reclaim) ? $volumes->volumes[$volname]->reclaim.'%' : '&nbsp;',
isset($volumes->volumes[$volname]->last['read']) ? tsmDate($volumes->volumes[$volname]->last['read'],'notime') : '&nbsp;',
isset($volumes->volumes[$volname]->last['write']) ? tsmDate($volumes->volumes[$volname]->last['write'],'notime') :
(isset($volumes->volumes[$volname]->dbv) ? tsmDate($volumes->volumes[$volname]->dbv['date'],'notime') : '&nbsp;'));
}
echo '</table></td></tr>';
echo '<tr><td colspan=3>&nbsp;</td></tr>';
} else {
printf('<tr><td colspan=2>'.
classValue(_('This is a %s library'),'value').
'</td><td>&nbsp;</td></tr>',
$library->type);
# Show the drives
foreach ($library->getDrives() as $drive) {
printf('<tr><td>&nbsp;</td><td>'.
classValue(_('Drive %s (Status %s).'),'value').
'</td><td>&nbsp;</td></tr>',
$drive->getName(),
$drive->volume ? sprintf('%s-%s',$drive->status,$drive->volume) : $drive->status);
}
echo '<tr><td colspan=3>&nbsp;</td></tr>';
}
echo '</table>';
}
} else {
echo _('No Library');
printf('<table><tr><td colspan=3>%s</td></tr></table>',
_('There are no automated libraries defined to this TSM server.'));
}
?>

39
htdocs/login.php Normal file
View File

@ -0,0 +1,39 @@
<?php
// $Header: /cvsroot/phptsmadmin/phpTSMadmin/htdocs/login.php,v 1.2 2009/04/19 04:00:59 wurley Exp $
/**
* Log the user in.
*
* @package leenooksApp
* @subpackage Page
*/
/**
*/
require './common.php';
$user = array();
$user['login'] = get_request('login');
$user['password'] = get_request('login_pass');
if ($user['login'] && ! strlen($user['password']))
system_message(array(
'title'=>_('Authenticate to server'),
'body'=>_('You left the password blank.'),
'type'=>'warn'),
sprintf('cmd.php?cmd=login_form&server_id=%s',get_request('server_id','REQUEST')));
if ($app['server']->login($user['login'],$user['password'],'user'))
system_message(array(
'title'=>_('Authenticate to server'),
'body'=>_('Successfully logged into server.'),
'type'=>'info'),
sprintf('cmd.php?server_id=%s',get_request('server_id','REQUEST')));
else
system_message(array(
'title'=>_('Failed to Authenticate to server'),
'body'=>_('Invalid Username or Password.'),
'type'=>'error'),
sprintf('cmd.php?cmd=login_form&server_id=%s',get_request('server_id','REQUEST')));
?>

90
htdocs/login_form.php Normal file
View File

@ -0,0 +1,90 @@
<?php
// $Header: /cvsroot/phptsmadmin/phpTSMadmin/htdocs/login_form.php,v 1.3 2009/04/19 04:00:59 wurley Exp $
/**
* Displays the login form for a server for users who specify 'cookie' or 'session' for their auth_type.
*
* @author Deon George (c) 2009
* @package leenooksApp
* @see login.php
*/
/**
*/
require './common.php';
printf('<h3 class="title">%s %s</h3>',_('Authenticate to server'),$app['server']->getName());
echo '<br />';
# Check for a secure connection
if (! isset($_SERVER['HTTPS']) || strtolower($_SERVER['HTTPS']) != 'on') {
echo '<center>';
echo '<span style="color:red">';
printf('<acronym title="%s"><b>%s: %s.</b></acronym>',
_('You are not using \'https\'. Web browser will transmit login information in clear text.'),
_('Warning'),_('This web connection is unencrypted'));
echo '</span>';
echo '</center>';
}
echo '<br />';
# Login form.
echo '<form action="cmd.php" method="post" name="login_form">';
echo '<input type="hidden" name="cmd" value="login" />';
printf('<input type="hidden" name="server_id" value="%s" />',$app['server']->getIndex());
if (get_request('redirect','GET',false,false))
printf('<input type="hidden" name="redirect" value="%s" />',rawurlencode(get_request('redirect','GET')));
echo '<center>';
echo '<table class="forminput">';
printf('<tr><td><b>%s:</b></td></tr>',
$app['server']->getValue('login','auth_text') ? $app['server']->getValue('login','auth_text') :
($app['server']->getValue('login','attr') == 'dn' ? _('Login DN') : $_SESSION[APPCONFIG]->getFriendlyName($app['server']->getValue('login','attr'))));
printf('<tr><td><input type="text" id="login" name="login" size="40" value="%s" /></td></tr>',
$app['server']->getValue('login','attr',false) == 'dn' ? $app['server']->getValue('login','bind_id') : '');
echo '<tr><td colspan=2>&nbsp;</td></tr>';
printf('<tr><td><b>%s:</b></td></tr>',_('Password'));
echo '<tr><td><input type="password" id="password" size="40" value="" name="login_pass" /></td></tr>';
echo '<tr><td colspan=2>&nbsp;</td></tr>';
if (method_exists($app['server'],'registerEnabled') && $app['server']->registerEnabled()) {
printf('<tr><td><center><a href="%s"><img src="%s" />&nbsp;%s</a></center></td></tr>','cmd.php?cmd=register_form',IMGDIR.'add.png',_('Register'));
echo '<tr><td colspan=2>&nbsp;</td></tr>';
}
# If Anon bind allowed, then disable the form if the user choose to bind anonymously.
if ($app['server']->isAnonBindAllowed())
printf('<tr><td colspan="2"><small><b>%s</b></small> <input type="checkbox" name="anonymous_bind" onclick="toggle_disable_login_fields(this)" id="anonymous_bind_checkbox" /></td></tr>',
_('Anonymous'));
printf('<tr><td colspan="2"><center><input type="submit" name="submit" value="%s" /></center></td></tr>',
_('Authenticate'));
echo '</table>';
echo '</center>';
echo '</form>';
echo '<script type="text/javascript" language="javascript">document.getElementById(\'login\').focus()</script>';
if ($app['server']->isAnonBindAllowed() ) {
?>
<script type="text/javascript" language="javascript">
function toggle_disable_login_fields(anon_checkbox) {
if (anon_checkbox.checked) {
anon_checkbox.form.login.disabled = true;
anon_checkbox.form.password.disabled = true;
} else {
anon_checkbox.form.login.disabled = false;
anon_checkbox.form.login.focus();
anon_checkbox.form.password.disabled = false;
}
}
</script>
<?php
}
?>

28
htdocs/logout.php Normal file
View File

@ -0,0 +1,28 @@
<?php
// $Header: /cvsroot/phptsmadmin/phpTSMadmin/htdocs/logout.php,v 1.2 2009/04/19 04:00:59 wurley Exp $
/**
* Log the user out of the application.
*
* @package leenooksApp
* @subpackage Page
*/
/**
*/
require './common.php';
if ($app['server']->logout('user'))
system_message(array(
'title'=>_('Authenticate to server'),
'body'=>_('Successfully logged out of server.'),
'type'=>'info'),
'index.php');
else
system_message(array(
'title'=>_('Failed to Logout of server'),
'body'=>_('Please report this error to the admins.'),
'type'=>'error'),
'index.php');
?>

297
htdocs/node.detail.php Normal file
View File

@ -0,0 +1,297 @@
<?php
// $Header: /cvsroot/phptsmadmin/phpTSMadmin/htdocs/node.detail.php,v 1.11 2009/04/19 04:57:32 wurley Exp $
# This page should detail on Client storage usage.
# Required Libraries
require './common.php';
/**
* This function returns an HTML table of the NODES FILE SYSTEMS for the $type
*/
function showFSDetails($node,$type) {
if (! $node->getFSOccupancy($type))
return null;
$blockBody = '<table class="result_table">';
switch ($type) {
case 'Bkup' :
$blockBody .= sprintf('<tr><td class="heading" colspan="%s">Backup Space Utilisation</td></tr>',
3+count($node->getStoragePools()));
break;
case 'Arch' :
$blockBody .= sprintf('<tr><td class="heading" colspan="%s">Archive Space Utilisation</td></tr>',
3+count($node->getStoragePools()));
break;
default:
return null;
}
$blockBody .= '<tr>';
$blockBody .= '<td class="titlel">File System</td>';
$blockBody .= '<td class="titlel">Last Backup</td>';
$blockBody .= '<td class="titler">Last Size</td>';
# List out the Storage Pools
foreach ($node->getStoragePools() as $stgp)
$blockBody .= sprintf('<td class="titler">%s</td>',$stgp);
$blockBody .= '</tr>';
$counter = 0;
foreach ($node->getFSOccupancy($type) as $fs => $object) {
$blockBody .= sprintf('<tr class="%s">',($counter++%2==0?'even':'odd'));
$blockBody .= sprintf('<td><acronym title="%s">%s</acronym></td>',
trim($object->type) ? $object->type : 'Unknown File System',$object->getName());
$blockBody .= sprintf('<td><acronym title="%s - %s">%s&nbsp;</acronym></td>',
isset($object->backup['start']) ? tsmdate($object->backup['start'],'nomsec') : 'NO START',
isset($object->backup['end']) ? tsmdate($object->backup['end'],'nomsec') : 'NO END',
isset($object->backup['end']) ? tsmdate($object->backup['end'],'notime') : 'NO DATE',
$object->getName());
$blockBody .= sprintf('<td align="right"><acronym title="%s MB (%s%%)">%s MB</acronym></td>',
isset($object->capacity) ? number_format($object->capacity) : '?',
isset($object->util) ? $object->util : '?',
number_format($object->capacity*$object->util/100));
foreach ($node->getStoragePools() as $stgp) {
if (isset($object->occupancy[$type][$stgp]))
$blockBody .= sprintf('<td align="right"><acronym title="%s files">%s</acronym>%s</td>',
number_format($object->occupancy[$type][$stgp]['num'],0),
number_format($object->occupancy[$type][$stgp]['physical'],2),
count($object->getVolumeUsage($stgp)) ? sprintf(' <acronym title="# Volumes"><sub>(%s)</sub></acronym>',count($object->getVolumeUsage($stgp))) : '');
else
$blockBody .= '<td>&nbsp;</td>';
}
$blockBody .= '</tr>';
}
$blockBody .= '</table>';
$blockBody .= "\n\n";
return $blockBody;
}
/**
* This function returns an HTML table of the VOLUMES used by a $node of $type
*/
function showVols($node,$type='Bkup') {
if (! $node->getVolumes($type))
return null;
$blockBody = '<table class="result_table">';
switch ($type) {
case 'Bkup' :
$blockBody .= sprintf('<tr><td class="heading" colspan="3">Backup Volume Utilisation</td></tr>');
break;
case 'Arch' :
$blockBody .= sprintf('<tr><td class="heading" colspan="3">Archive Volume Utilisation</td></tr>');
break;
default:
return null;
}
$blockBody .= '<tr>';
$blockBody .= '<td class="titlel">File System</td>';
$blockBody .= '<td class="titlel">Storage Pool</td>';
$blockBody .= '<td class="titlel">Volume</td>';
$blockBody .= '</tr>';
$last['stg'] = '';
$last['fs'] = '';
$counter = 0;
foreach ($node->getVolumes($type) as $fs => $object) {
foreach ($object->volume[$type] as $stgp => $volumes) {
foreach ($volumes as $vol => $volume) {
$blockBody .= sprintf('<tr class="%s"><td>%s</td><td>%s</td><td>%s</td></tr>',
($counter%2==0?'even':'odd'),
$object->getName() == $last['fs'] ? '' : $object->getName(),
$stgp == $last['stg'] ? '' : $stgp,
sprintf('%s (%s/%s%s)',$vol,
$volume->status['volume'],$volume->access,
trim($volume->location) ? '-'.$volume->location : ''));
$last['stg'] = $stgp;
$last['fs'] = $object->getName();
}
$counter++;
}
}
$blockBody .= '</table>';
$blockBody .= "\n\n";
return $blockBody;
}
/**
* This function returns an HTML table of the VOLUMES by PRIMARY/COPY used by a $node of $type
*/
function showAllvols($node,$type='Bkup') {
if (! $node->getVolumes($type))
return null;
$blockBody = '<table class="result_table">';
switch ($type) {
case 'Bkup' :
$blockBody .= sprintf('<tr><td class="heading" colspan="2">Backup Volume Utilisation</td></tr>');
break;
case 'Arch' :
$blockBody .= sprintf('<tr><td class="heading" colspan="2">Archive Volume Utilisation</td></tr>');
break;
default:
return null;
}
$counter = 0;
foreach ($node->getPrimaryVolumes($type) as $volumename => $volume) {
$blockBody .= sprintf('<tr class="%s"><td>%s</td><td>%s</td></tr>',
($counter%2==0?'even':'odd'),
! $counter ? 'Primary' : '&nbsp;',
sprintf('%s (%s/%s%s)',$volume->getName(),
$volume->status['volume'],$volume->access,
trim($volume->location) ? '-'.$volume->location : ''));
$counter++;
}
$counter = 0;
foreach ($node->getCopyVolumes($type) as $volumename => $volume) {
$blockBody .= sprintf('<tr class="%s"><td>%s</td><td>%s</td></tr>',
($counter%2==0?'even':'odd'),
! $counter ? 'Copy' : '&nbsp;',
sprintf('%s (%s/%s%s)',$volume->getName(),
$volume->status['volume'],$volume->access,
trim($volume->location) ? '-'.$volume->location : ''));
$counter++;
}
$blockBody .= '</table>';
$blockBody .= "\n\n";
return $blockBody;
}
# Defaults
$nodes = objectCache('nodes');
$mgmtclass = objectCache('mgmtclasses');
# List of Clients.
printf(_('Select NODE on %s'),$app['server']->getValue('server','name'));
echo '<form action="cmd.php">';
printf('<input type="hidden" name="cmd" value="%s" />',get_request('cmd','REQUEST'));
printf('<input type="hidden" name="index" value="%s" />',$app['server']->getIndex());
echo '<select name="NODE">';
foreach ($nodes->getNodes() as $node) {
printf('<option id="%s" %s>%s</option>',
$node->getName(),
isset($_REQUEST['NODE']) && $node->getName() == $_REQUEST['NODE'] ? 'selected' : '',
$node->getName());
}
echo '</select>';
echo '<input align="left" type="submit" name="submit" value="Go" />';
echo '</form>';
echo "\n";
if (isset($_REQUEST['NODE'])) {
echo '<br />';
echo '<table class="result" width=100% border=0>';
printf('<tr><td colspan=3><h3>NODE detail for <u>%s</u> on %s</h3></td></tr>',
$_REQUEST['NODE'],$app['server']->getValue('server','name'));
$node = $nodes->nodes[$_REQUEST['NODE']];
if ($node->url)
printf('<tr><td colspan=2>System Name</td><td><a href="%s"><b>%s</b></a></td></tr>',
$node->url,$node->hostname);
else
printf('<tr><td colspan=2>System Name</td><td><b>%s</b></td></tr>',$node->hostname ? $node->hostname : '&nbsp;');
printf('<tr><td colspan=2>Contact</td><td><b>%s</b></td></tr>',$node->contact ? $node->contact : '&nbsp;');
printf('<tr><td colspan=2>OS</td><td><b>%s (%s)</b></td></tr>',
$node->os,$node->level['os']);
printf('<tr><td colspan=2>TSM Client Version</td><td><b>%s.%s.%s.%s</b></td></tr>',
$node->level['tsm_ver'],$node->level['tsm_rel'],$node->level['tsm_lvl'],$node->level['tsm_slv']);
echo '<tr><td colspan=3><h4>Access Information</h4></td></tr>';
printf('<tr><td colspan=2>Registered</td><td><b>%s</b></td></tr>',
tsmDate($node->time['registered'],'nosec'));
printf('<tr><td colspan=2>Last Accessed</td><td><b>%s</b> (%2.0f days ago)</td></tr>',
tsmDate($node->time['lastacc'],'nosec'),
(time()-strtotime(tsmDate($node->time['lastacc'],'nosec')))/86400);
printf('<tr><td colspan=2>Last Password Change</td><td><b>%s</b> (%2.0f days ago)</td></tr>',
tsmDate($node->time['pwset'],'nosec'),
(time()-strtotime(tsmDate($node->time['pwset'],'nosec')))/86400);
printf('<tr><td colspan=2>Password Expiry</td><td><b>%s</b></td></tr>',
tsmDate($node->passwd['expiry'],'nosec') ? tsmDate($node->passwd['expiry'],'nosec') : '&nbsp;');
printf('<tr><td colspan=2>Invalid Password Count</td><td><b>%s</b> (%s)</td></tr>',
$node->passwd['invalid'],
$node->locked ? 'LOCKED' : 'NOT Locked');
echo '<tr><td colspan=3><h4>Configuration Options</h4></td></tr>';
printf('<tr><td colspan=2>Option Set</td><td><b>%s</b></td></tr>',$node->cloptset ? $node->cloptset : '&nbsp;');
printf('<tr><td colspan=2>Compression </td><td><b>%s</b></td></tr>',
$node->compression ? 'YES' : 'NO');
printf('<tr><td colspan=2>TXN Group Max</td><td><b>%s</b></td></tr>',$node->txngroupmax ? $node->txngroupmax : '&nbsp;');
printf('<tr><td colspan=2>Can Delete Archives</td><td><b>%s</b></td></tr>',
$node->delete['arch'] ? 'YES' : 'NO');
printf('<tr><td colspan=2>Can Delete Backups</td><td><b>%s</b></td></tr>',
$node->delete['back'] ? 'YES' : 'NO');
printf('<tr><td colspan=2>Keep Mount Points</td><td><b>%s</b> (%s)</td></tr>',
$node->mp['keep'] ? 'YES' : 'NO',$node->mp['max']);
echo '<tr><td colspan=3><h4>Storage Configuration</h4></td></tr>';
printf('<tr><td colspan=2>Colloc Group Name</td><td><b>%s</b></td></tr>',$node->group ? $node->group : _('Not Set'));
echo '<tr><td colspan=3>&nbsp;</td></tr>';
printf('<tr><td colspan=2>Backup Domain</td><td><b>%s</b></td></tr>',$node->domain);
# Show the MGMTClasses that apply to this node.
printf('<tr><td>&nbsp;</td><td colspan=2><i>Available Backup Management Classes</i></td></tr>');
foreach ($mgmtclass->getMgmtClasses($node->domain,'Bkup') as $object) {
if (is_object($object))
printf('<tr><td>&nbsp;</td><td><acronym title="File Exists: %s Version(s)/%s Day(s), File Deleted: %s Version(s)/%s Day(s), Frequency: %s Day(s)"><b>%s</b></acronym>%s</td><td>Storage Pool: <b>%s</b></td></tr>',
$object->version['EXISTS'],$object->retain['EXTRA'],$object->version['DELETED'],$object->retain['ONLY'],$object->frequency,$object->getName(),
$object->isDefaultMgmtClass() ? ' <sub>(Default)</sub>' : '',
$object->getStoragePool() ? $object->getStoragePool()->getName() : sprintf('<sub>(%s)</sub>',_('Storage Pool Doesnt Exist')));
}
printf('<tr><td>&nbsp;</td><td colspan=2><i>Available Archive Management Classes</i></td></tr>');
foreach ($mgmtclass->getMgmtClasses($node->domain,'Arch') as $object) {
if (is_object($object))
printf('<tr><td>&nbsp;</td><td><acronym title="Days: %s"><b>%s</b></acronym>%s</td><td>Storage Pool: <b>%s</b></td></tr>',
$object->retain['DAYS'],$object->getName(),
$object->isDefaultMgmtClass() ? ' <sub>(Default)</sub>' : '',
$object->getStoragePool() ? $object->getStoragePool()->getName() : sprintf('<sub>(%s)</sub>',_('Storage Pool Doesnt Exist')));
}
echo '<tr><td colspan=3><h4>Storage Utilisation</h4></td></tr>';
if ($node->getFileSystems()) {
printf('<tr><td colspan=3>%s</td></tr>',showFSDetails($node,'Bkup'));
echo '<tr><td colspan=3>&nbsp;</td></tr>';
printf('<tr><td colspan=3>%s</td></tr>',showFSDetails($node,'Arch'));
} else {
echo '<tr><td colspan=3>TSM does not have any data for this host.</td></tr>';
}
if (count($node->getVolumeUsage())) {
echo '<tr><td colspan=3><h4>Volume Utilisation</h4></td></tr>';
printf('<tr><td colspan=3>%s</td></tr>',showAllVols($node,'Bkup'));
echo '<tr><td colspan=3>&nbsp;</td></tr>';
printf('<tr><td colspan=3>%s</td></tr>',showAllVols($node,'Arch'));
echo '<tr><td colspan=3><h4>Volume Utilisation by File System</h4></td></tr>';
printf('<tr><td colspan=3>%s</td></tr>',showVols($node,'Bkup'));
echo '<tr><td colspan=3>&nbsp;</td></tr>';
printf('<tr><td colspan=3>%s</td></tr>',showVols($node,'Arch'));
}
echo '</table>';
}
?>

92
htdocs/node.occupancy.php Normal file
View File

@ -0,0 +1,92 @@
<?php
// $Header: /cvsroot/phptsmadmin/phpTSMadmin/htdocs/node.occupancy.php,v 1.9 2009/04/19 04:57:32 wurley Exp $
# This page should return the summary of the client occupancy.
# Required Libraries
require './common.php';
# Defaults
$nodes = objectCache('nodes');
# Header
$blockTitle['graph'] = sprintf(_('Client Occupancy Summary on %s'),$app['server']->getValue('server','name'));
$blockBody['graph'] = '<table class="result_table">';
$blockTitle['occ'] = sprintf(_('Client Occupancy Summary on %s'),$app['server']->getValue('server','name'));
$blockBody['occ'] = '<table class="result_table">';
$counter = 0;
$grandtotal = 0;
# Work out our stgpools with data in them.
$stgpooltotal = array();
$blockBody['occ'] .= sprintf('<tr><td class="heading">%s</td><td class="heading">%s</td><td class="heading">%s</td>',
'Node','Last Acc','Type');
foreach ($nodes->getNodes() as $node) {
foreach ($node->getStoragePools() as $stgp) {
if (! isset($stgpooltotal[$stgp])) {
$blockBody['occ'] .= sprintf('<td class="heading">%s</td>',$stgp);
$stgpooltotal[$stgp] = 0;
}
}
}
$blockBody['occ'] .= sprintf('<td class="heading">%s</td></tr>','Total');
# Now show the nodes having data in the stgpools.
$history = array();
foreach ($nodes->getNodes() as $node) {
foreach ($node->getOccupancy() as $type => $stgpools) {
$nodetotal = 0;
$blockBody['occ'] .= sprintf('<tr class="%s"><td>%s</td><td>%s</td><td>%s</td>',
($counter++%2==0?'even':'odd'),
$node->getName(),
tsmDate($node->time['lastacc'],'notime'),
$type);
foreach ($stgpooltotal as $stgpool => $details) {
if (isset($stgpools[$stgpool])) {
$blockBody['occ'] .= sprintf('<td align="right">%s</td>',number_format($stgpools[$stgpool]['physical']));
$nodetotal += $stgpools[$stgpool]['physical'];
$stgpooltotal[$stgpool] += $stgpools[$stgpool]['physical'];
} else
$blockBody['occ'] .= sprintf('<td>%s</td>','&nbsp;');
}
$blockBody['occ'] .= sprintf('<td align="right">&nbsp;%s</td></tr>',number_format($nodetotal));
$grandtotal += $nodetotal;
$oldtime = strtotime(tsmDate($node->time['lastacc'],'sec'));
$diff = round((time() - $oldtime)/86400);
@$history[$diff] += $nodetotal;
}
}
# Store our history information for when we call the graphing php.
$_SESSION['graph']['occupancy'] = $history;
ksort($_SESSION['graph']['occupancy']);
# Show our dbbackup graph
$blockBody['graph'] .= '<tr><td><table class="result_table">';
$blockBody['graph'] .= sprintf('<tr><td class="heading">%s</td><td class="heading">%s</td><td class="heading">%%</td></tr>','Days Since Access','Storage Used');
$counter = 0;
foreach ($_SESSION['graph']['occupancy'] as $age => $size) {
$blockBody['graph'] .= sprintf('<tr class="%s"><td>%s</td><td align="right">%s</td><td align="right">%s</td></tr>',
($counter++%2==0?'even':'odd'),$age,number_format($size),sprintf('%2.1f%%',$size/$grandtotal*100));
}
$blockBody['graph'] .= '</table></td>';
$blockBody['graph'] .= '<td>&nbsp;</td>';
$blockBody['graph'] .= sprintf('<td align="right"><img src="image.occupancy.php?index=%s" /></td></tr>',
$app['server']->getIndex());
$blockBody['graph'] .= '</table>';
$blockBody['occ'] .= sprintf('<tr class="highlight"><td class="titlel" colspan=3>%s</td>','TOTAL');
foreach ($stgpooltotal as $stgpool => $total)
$blockBody['occ'] .= sprintf('<td class="titler">%s</td>',number_format($total));
$blockBody['occ'] .= sprintf('<td class="titler">&nbsp;%s</td></tr>',number_format($grandtotal));
$blockBody['occ'] .= '</table>';
# End
render_page($blockTitle,$blockBody);
?>

126
htdocs/node.summary.php Normal file
View File

@ -0,0 +1,126 @@
<?php
// $Header: /cvsroot/phptsmadmin/phpTSMadmin/htdocs/node.summary.php,v 1.5 2009/04/19 04:00:59 wurley Exp $
# This page should return all a summary of Client activitie, for the last 24 hours.
# @TODO: Need to allow for multiple schedules in 1 day.
# Required Libraries
require './common.php';
# Defaults
$todayDate = date('Y-m-d H:i');
$yesterDate = date('Y-m-d H:i',time()-86400);
$summaryInfo = objectCache('summaryinfo');
$nodes = objectCache('nodes');
# Data collection.
$tsmBackupSummary = $app['server']->GetActlogBackupSummary($yesterDate,$todayDate);
# Database Summary Information
$blockTitle['sched'] = sprintf(_('Client Schedule Activity on %s'),$app['server']->getValue('server','name'));
$blockBody['sched'] = '<table border=0>';
$blockBody['sched'] .= '<tr><td width=100%><table class="result" width=100%>';
$blockBody['sched'] .= sprintf('<tr><td class="titlel">%s</td><td class="titlel">%s</td><td class="titlel">%s</td><td class="titlel">%s</td></tr>',
'Client','Schedule','Sched Status','Sched Start');
$counter = 0;
$events = $app['server']->GetEvents($yesterDate,$todayDate,'ACTUAL_START');
if (count($events['detail'])) {
foreach ($events['detail'] as $index => $tsmEvent) {
$node = $nodes->getNode($tsmEvent['NODE_NAME']);
$blockBody['sched'] .= sprintf('<tr class="%s"><td><acronym title="%s (%s.%s.%s.%s)">%s</acronym></td><td>%s</td><td><acronym title="Result Code %s">%s</acronym></td><td>%s</td></tr>',
$tsmEvent['STATUS'] == 'Failed' ? 'highlight' : ($counter++%2==0?'even':'odd'),
$node->os,
$node->level['tsm_ver'],$node->level['tsm_rel'],$node->level['tsm_lvl'],$node->level['tsm_slv'],
$tsmEvent['NODE_NAME'],
$tsmEvent['SCHEDULE_NAME'],
$tsmEvent['RESULT'],$tsmEvent['STATUS'],
tsmDate($tsmEvent['ACTUAL_START']));
$key = $tsmEvent['STATUS'].' '.$tsmEvent['RESULT'];
@$graph['data'][$tsmEvent['SCHEDULE_NAME']][$key]++;
@$graph['legend'][$key]++;
}
} else {
$graph = false;
}
$blockBody['sched'] .= '</table></td>';
if ($graph) {
$_SESSION['graph']['backupevent'] = $graph;
$blockBody['sched'] .= sprintf('<td align="right"><img src="image.backupevents.php?index=%s" /></td>',
$app['server']->getIndex());
}
$blockBody['sched'] .= '</tr></table>';
$blockTitle['backup'] = sprintf(_('Client Backup Session Summary on %s'),$app['server']->getValue('server','name'));
$blockBody['backup'] = '<table class="result">';
$blockBody['backup'] .= sprintf('<tr><td class="titlel">%s</td><td class="titlel">%s</td><td class="titlel">%s</td><td class="titlel">%s</td><td class="titler">%s</td><td class="titler">%s</td><td class="titler">%s</td><td class="titler">%s</td><td class="titler">%s</td><td class="titler">%s</td><td class="titler">%s</td><td class="titler">%s</td></tr>',
'Client','Sched','Date','Type','Session','Inspected','Backed Up','Failed','Time','MB','Agg Rate Kb/s','Compressed');
$counter = 0;
$summary = $summaryInfo->getSummary($yesterDate,$todayDate);
if (! count($summary))
$blockBody['backup'] .= sprintf('<tr><td colspan=0>%s</td></tr>','No summary');
else
foreach ($summary as $tsmSession) {
if (! in_array($tsmSession['ACTIVITY'],array('BACKUP','ARCHIVE'))) continue;
# Summary Information
$client_summary = sprintf('Update: %s, Rebound: %s, Delete: %s, Expire: %s.',
(isset($tsmBackupSummary['detail'][$tsmSession['ENTITY']][$tsmSession['NUMBER']]['Update']) ? $tsmBackupSummary['detail'][$tsmSession['ENTITY']][$tsmSession['NUMBER']]['Update'] : '-'),
(isset($tsmBackupSummary['detail'][$tsmSession['ENTITY']][$tsmSession['NUMBER']]['Rebound']) ? $tsmBackupSummary['detail'][$tsmSession['ENTITY']][$tsmSession['NUMBER']]['Rebound'] : '-'),
(isset($tsmBackupSummary['detail'][$tsmSession['ENTITY']][$tsmSession['NUMBER']]['Delete']) ? $tsmBackupSummary['detail'][$tsmSession['ENTITY']][$tsmSession['NUMBER']]['Delete'] : '-'),
(isset($tsmBackupSummary['detail'][$tsmSession['ENTITY']][$tsmSession['NUMBER']]['Expire']) ? $tsmBackupSummary['detail'][$tsmSession['ENTITY']][$tsmSession['NUMBER']]['Expire'] : '-'));
$blockBody['backup'] .= sprintf('<tr class="%s"><td>%s</td><td>%s</td><td>%s</td><td><acronym title="%s">%s</acronym></td><td align="right">%s</td><td align="right">%s</td><td align="right">%s</td><td align="right">%s</td><td align="right">%s</td><td align="right">%s</td><td align="right">%s</td><td align="right">%s</td></tr>',
($counter++%2==0?'even':'odd'),
$tsmSession['ENTITY'],
$tsmSession['SCHEDULE_NAME'],
tsmDate($tsmSession['START_TIME'],'daytime'),
$client_summary,
$tsmSession['ACTIVITY'],
$tsmSession['NUMBER'],
number_format($tsmSession['EXAMINED']),
$tsmSession['AFFECTED'],
(isset($tsmBackupSummary['detail'][$tsmSession['ENTITY']][$tsmSession['NUMBER']]['Failed']) ? $tsmBackupSummary['detail'][$tsmSession['ENTITY']][$tsmSession['NUMBER']]['Failed'] : '-'),
(isset($tsmBackupSummary['detail'][$tsmSession['ENTITY']][$tsmSession['NUMBER']]['ProcTime']) ? $tsmBackupSummary['detail'][$tsmSession['ENTITY']][$tsmSession['NUMBER']]['ProcTime'] : '-'),
sprintf('%3.2f',$tsmSession['BYTES']/1024/1024),
(isset($tsmBackupSummary['detail'][$tsmSession['ENTITY']][$tsmSession['NUMBER']]['AggRate']) ? $tsmBackupSummary['detail'][$tsmSession['ENTITY']][$tsmSession['NUMBER']]['AggRate'] : '-'),
(isset($tsmBackupSummary['detail'][$tsmSession['ENTITY']][$tsmSession['NUMBER']]['Compress']) ? $tsmBackupSummary['detail'][$tsmSession['ENTITY']][$tsmSession['NUMBER']]['Compress'] : '-'));
}
$blockBody['backup'] .= '</table>';
$counter = 0;
$blockTitle['restore'] = sprintf(_('Client Restore Session Summary on %s'),$app['server']->getValue('server','name'));
$blockBody['restore'] = '<table class="result">';
$blockBody['restore'] .= sprintf('<tr><td class="titlel">%s</td><td class="titlel">%s</td><td class="titlel">%s</td><td class="titlel">%s</td><td class="titler">%s</td><td class="titler">%s</td><td class="titler">%s</td><td class="titler">%s</td><td class="titler">%s</td><td class="titler">%s</td></tr>',
'Client','Time','Session','Type','Restored','Failed','Media W','Time','MB','Agg Rate Kb/s');
foreach ($summary as $tsmSession) {
if (! in_array($tsmSession['ACTIVITY'],array('RESTORE','RETRIEVE'))) continue;
$blockBody['restore'] .= sprintf('<tr class="%s"><td>%s</td><td>%s</td><td>%s</td><td>%s</td><td align="right">%s</td><td align="right">%s</td><td align="right">%s</td><td align="right">%s</td><td align="right">%s</td><td align="right">%s</td></tr>',
($counter++%2==0?'even':'odd'),
$tsmSession['ENTITY'],
tsmDate($tsmSession['START_TIME'],'nosec'),
$tsmSession['NUMBER'],
$tsmSession['ACTIVITY'],
$tsmSession['AFFECTED'],
$tsmSession['FAILED'],
$tsmSession['MEDIAW'],
(isset($tsmBackupSummary['detail'][$tsmSession['ENTITY']][$tsmSession['NUMBER']]['ProcTime']) ? $tsmBackupSummary['detail'][$tsmSession['ENTITY']][$tsmSession['NUMBER']]['ProcTime'] : '-'),
sprintf('%3.1fMB',$tsmSession['BYTES']/1024/1024),
(isset($tsmBackupSummary['detail'][$tsmSession['ENTITY']][$tsmSession['NUMBER']]['AggRate']) ? $tsmBackupSummary['detail'][$tsmSession['ENTITY']][$tsmSession['NUMBER']]['AggRate'] : '-'),
$tsmSession['SCHEDULE_NAME']);
}
$blockBody['restore'] .= '</table>';
# End
render_page($blockTitle,$blockBody);
?>

21
htdocs/node.thruput.php Normal file
View File

@ -0,0 +1,21 @@
<?php
// $Header: /cvsroot/phptsmadmin/phpTSMadmin/htdocs/node.thruput.php,v 1.1 2009/04/19 05:27:13 wurley Exp $
# This page should show recent client thruput
# Required Libraries
require './common.php';
$thruput = $app['server']->query("SELECT substr(varchar(END_TIME),1,10) as ADATE,ENTITY,ACTIVITY,cast(float(sum(BYTES))/1024/1024/1024 as dec(8,2)) as GB from SUMMARY where ACTIVITY='BACKUP' and END_TIME>CURRENT_TIMESTAMP-(30)DAY and (ACTIVITY in ('ARCHIVE','BACKUP','RESTORE','RETRIEVE')) group by END_TIME,ENTITY,ACTIVITY order by ADATE desc,ENTITY ",null,false,false);
echo '<table class="result_table">';
printf('<tr class="%s"><td>%s</td><td>%s</td><td>%s</td><td>%s</td></tr>',
'heading','Date','Node','Type','GB');
$counter = 0;
foreach ($thruput as $details) {
printf('<tr class="%s"><td>%s</td><td>%s</td><td>%s</td><td>%s</td></tr>',
$counter++%2 ? 'even' : 'odd',
$details['ADATE'],$details['ENTITY'],$details['ACTIVITY'],$details['GB']);
}
echo '</table>';
?>

35
htdocs/purge_cache.php Normal file
View File

@ -0,0 +1,35 @@
<?php
// $Header: /cvsroot/phptsmadmin/phpTSMadmin/htdocs/purge_cache.php,v 1.1 2008/01/14 22:13:26 wurley Exp $
/**
* @package leenooksApp
*/
require './common.php';
if (! $_SESSION[APPCONFIG]->isCommandAvailable('purge')) {
error(sprintf('%s%s %s',_('This operation is not permitted by the configuration'),_(':'),_('purge')),'warn');
return;
}
$purge_session_keys = array('cache');
$size = 0;
foreach ($purge_session_keys as $key) {
if (isset($_SESSION[$key])) {
$size += strlen(serialize($_SESSION[$key]));
unset($_SESSION[$key]);
}
}
if (! $size)
$body = _('No cache to purge.');
else
$body = sprintf(_('Purged %s bytes of cache.'),number_format($size));
system_message(array(
'title'=>_('Purge cache'),
'body'=>$body,
'type'=>'info'),
'index.php');
?>

17
htdocs/schedule.gantt.php Normal file
View File

@ -0,0 +1,17 @@
<?php
// $Header: /cvsroot/phptsmadmin/phpTSMadmin/htdocs/schedule.gantt.php,v 1.4 2009/04/19 04:00:59 wurley Exp $
# @todo: Hotlink the hostname to the detail script.
# Required Libraries
require './common.php';
initJPGraph(true);
$blockTitle['gantt'] = sprintf(_('Schedule Gantt for server %s'),$app['server']->getValue('server','name'));
$blockBody['gantt'] = '<table class="result"><tr><td>';
$blockBody['gantt'] .= sprintf('<img src="%s?index=%s" border=0 />','image.schedule.gantt.php',$app['server']->getIndex()) ;
$blockBody['gantt'] .= '</td></tr></table>';
# End
render_page($blockTitle,$blockBody);
?>

145
htdocs/server.db.php Normal file
View File

@ -0,0 +1,145 @@
<?php
// $Header: /cvsroot/phptsmadmin/phpTSMadmin/htdocs/server.db.php,v 1.12 2009/04/19 04:00:59 wurley Exp $
# This page should return all information about tde TSM database.
# Required Libraries
require './common.php';
# Database Summary Information
$blockTitle['db'] = sprintf(_('Database Information for %s (%s) %s.%s.%s.%s'),
$app['server']->GetStatusDetail('SERVER_NAME'),
$app['server']->GetStatusDetail('PLATFORM'),
$app['server']->GetStatusDetail('VERSION'),
$app['server']->GetStatusDetail('RELEASE'),
$app['server']->GetStatusDetail('LEVEL'),
$app['server']->GetStatusDetail('SUBLEVEL'));
$blockBody['db'] = '<table class="blockcitem">';
$blockBody['db'] .= sprintf('<tr><td colspan=2 class="titlel">%s</td></tr>',_('Database Summary'));
$blockBody['db'] .= '<tr><td><table class="result" border=0>';
$blockBody['db'] .= sprintf('<tr><td colspan=2>'.classValue(_('%s DB volumes totaling %sMB (%s%% utilsed).'),'value').'</td></tr>',
$app['server']->GetDBDetail('PHYSICAL_VOLUMES'),$app['server']->GetDBDetail('AVAIL_SPACE_MB'),
$app['server']->GetDBDetail('PCT_UTILIZED'));
foreach ($app['server']->GetDBDetail('dbvols') as $key) {
$blockBody['db'] .= sprintf('<tr><td>&nbsp;</td><td>'.classValue(_('%s (%sMB) (%sMB Free) (%s).'),'value').'</td></tr>',
$key['COPY1_NAME'],$key['AVAIL_SPACE_MB'],$key['FREE_SPACE_MB'],$key['COPY1_STATUS']);
if ($key['COPY2_NAME'])
$blockBody['db'] .= sprintf('<tr><td>&nbsp;</td><td>'.classValue(_('%s (%s).'),'value').'</td></tr>',
$key['COPY2_NAME'],$key['COPY2_STATUS']);
if ($key['COPY3_NAME'])
$blockBody['db'] .= sprintf('<tr><td>&nbsp;</td><td>'.classValue(_('%s (%s).'),'value').'</td></tr>',
$key['COPY3_NAME'],$key['COPY3_STATUS']);
}
$blockBody['db'] .= '<tr><td colspan=2>&nbsp;</td></tr>';
$blockBody['db'] .= sprintf('<tr><td colspan=2>'.classValue(_('%s LOG volumes totaling %sMB (%s%% utilsed).'),'value').'</td></tr>',
$app['server']->GetLogDetail('PHYSICAL_VOLUMES'),$app['server']->GetLogDetail('AVAIL_SPACE_MB'),
$app['server']->GetLogDetail('PCT_UTILIZED'));
foreach ($app['server']->GetLogDetail('logvols') as $key) {
$blockBody['db'] .= sprintf('<tr><td>&nbsp;</td><td>'.classValue(_('%s (%sMB) (%sMB Free) (%s).'),'value').'</td></tr>',
$key['COPY1_NAME'],$key['AVAIL_SPACE_MB'],$key['FREE_SPACE_MB'],$key['COPY1_STATUS']);
if ($key['COPY2_NAME'])
$blockBody['db'] .= sprintf('<tr><td>&nbsp;</td><td>'.classValue(_('%s (%s).'),'value').'</td></tr>',
$key['COPY2_NAME'],$key['COPY2_STATUS']);
if ($key['COPY3_NAME'])
$blockBody['db'] .= sprintf('<tr><td>&nbsp;</td><td>'.classValue(_('%s (%s).'),'value').'</td></tr>',
$key['COPY3_NAME'],$key['COPY3_STATUS']);
}
$blockBody['db'] .= '<tr><td colspan=2>&nbsp;</td></tr>';
$blockBody['db'] .= sprintf('<tr><td colspan=2>'.classValue(_('Database REDO log mode %s.'),'value').'</td></tr>',
$app['server']->GetStatusDetail('LOGMODE'));
$blockBody['db'] .= '<tr><td colspan=2>&nbsp;</td></tr>';
$blockBody['db'] .= sprintf('<tr><td colspan=2>'.classValue(_('%s%% database cache hit rate (%s%% cache wait).'),'value').'</td></tr>',
$app['server']->GetDBDetail('CACHE_HIT_PCT'),$app['server']->GetDBDetail('CACHE_WAIT_PCT'));
if ($trigger = $app['server']->GetDBBackupDetail('trigger')) {
$blockBody['db'] .= '<tr><td colspan=2>&nbsp;</td></tr>';
$blockBody['db'] .= sprintf('<tr><td colspan=2>'.classValue(_('TSM will automatically backup the database to %s when the logs reach %s%% full.'),'value').'</td></tr>',
sprintf('<a href="cmd.php?cmd=devclass.info&index=%s&devclass=%s">%s</a>',$app['server']->getIndex(),$trigger['INCRDEVCLASS'],$trigger['INCRDEVCLASS']),
$trigger['LOGFULLPCT']);
$blockBody['db'] .= sprintf('<tr><td colspan=2>'.classValue(_('After %s INCREMENTAL backups, a full backup will be performed to %s.'),'value').'</td></tr>',
$trigger['NUMICREMENTAL'],
sprintf('<a href="cmd.php?cmd=devclass.info&index=%s&devclass=%s">%s</a>',$app['server']->getIndex(),$trigger['DEVCLASS'],$trigger['DEVCLASS']));
}
$blockBody['db'] .= '</table></td>';
# Show our dbbackup graph
$blockBody['db'] .= sprintf('<td align="right"><img src="image.dbbackuphistory.php?index=%s" /></td></tr>',
$app['server']->getIndex());
$blockBody['db'] .= '</table>';
# Database Backup Information
$blockTitle['backup'] = sprintf(_('Database backup information for %s'),$app['server']->getValue('server','name'));
$blockBody['backup'] = '<table class="result">';
if ($app['server']->GetDBDetail('LAST_BACKUP_DATE')) {
$blockBody['backup'] .= sprintf('<tr><td colspan=6>'.classValue(_('%sMB (%s%%) has changed since the last backup on %s'),'value').'</td></tr>',
$app['server']->GetDBDetail('BACKUP_CHG_MB'),$app['server']->GetDBDetail('BACKUP_CHG_PCT'),
tsmDate($app['server']->GetDBDetail('LAST_BACKUP_DATE')));
$blockBody['backup'] .= '<tr><td colspan=6>&nbsp;</td></tr>';
## Show DB Vols
$blockBody['backup'] .= sprintf('<tr><td colspan=6>'.classValue(_('%s backups between %s and %s available for TSM DB restore.'),'value').'</td></tr>',
tsmDate($app['server']->GetDBBackupDetail('count'),'nosec'),
tsmDate($app['server']->GetDBBackupDetail('first'),'nosec'),
tsmDate($app['server']->GetDBBackupDetail('last'),'nosec'));
$blockBody['backup'] .= sprintf('<tr><td class="titlel">&nbsp;</td><td class="titlel">%s</td><td class="titlel">%s</td><td class="titlel">%s</td><td class="titlel">%s</td><td class="titlel">%s</td><td class="titlel">%s</td><td class="titlel">%s</td></tr>',
'SEQ #','DATE','TYPE','DEVICE','VOLUME','LOCATION','STATUS');
$counter = 0;
$lastseries = 0;
foreach ($app['server']->GetDBBackupDetail('vols') as $volname => $voldetails) {
if (! is_array($voldetails))
continue;
if ($lastseries != $voldetails['BACKUP_SERIES']) {
$lastseries = $voldetails['BACKUP_SERIES'];
$counter ++;
}
$blockBody['backup'] .= sprintf('<tr %s><td>&nbsp;</td><td>%s</td><td>%s</td><td>%s</td><td>%s</td><td>%s</td><td>%s</td><td>%s</td></tr>',
($voldetails['STATUS'] == 'InValid' ? 'class="shadow"' : ($counter%2==0?'class="even"':'class="odd"')),
sprintf('%s-%s-%s',$voldetails['BACKUP_SERIES'],$voldetails['BACKUP_OPERATION'],$voldetails['VOLUME_SEQ']),
tsmDate($voldetails['DATE_TIME'],'nosec'),
tsmBackupType($voldetails['TYPE']),
$voldetails['DEVCLASS'],
$volname,
$app['server']->GetVolLocation($volname),
$voldetails['STATUS']);
}
$blockBody['backup'] .= '<tr><td colspan=4>&nbsp;</td></tr>';
} else {
$blockBody['backup'] .= sprintf('<tr><td colspan=6>%s</td></tr>',_('It looks like you have NOT yet run a TSM backup.'));
}
if ($app['server']->GetDBDetail('BACKUP_RUNNING') == 'YES')
$blockBody['backup'] .= sprintf('<tr><td colspan=6>%s</td></tr>',_('Database backup IS currently running.'));
else
$blockBody['backup'] .= sprintf('<tr><td colspan=6>%s</td></tr>',_('Database backup is NOT currently running.'));
$blockBody['backup'] .= '<tr><td colspan=6>&nbsp;</td></tr>';
$blockBody['backup'] .= '</table>';
# End
render_page($blockTitle,$blockBody);
?>

103
htdocs/server.stats.php Normal file
View File

@ -0,0 +1,103 @@
<?php
// $Header: /cvsroot/phptsmadmin/phpTSMadmin/htdocs/server.stats.php,v 1.6 2009/04/19 04:00:59 wurley Exp $
# Required Libraries
require './common.php';
$summaryInfo = objectCache('summaryinfo');
if (! isset($_REQUEST['mediaactions'])) {
$blockTitle['form'] = _('Graph Media Statistics.');
$blockBody['form'] = 'Please select the stats you would like to graph.';
$blockBody['form'] .= '<form action="cmd.php">';
$blockBody['form'] .= sprintf('<input type="hidden" name="cmd" value="%s" />',get_request('cmd','REQUEST'));
$blockBody['form'] .= '<select multiple size=10 name="mediaactions[]">';
foreach ($summaryInfo->mediaActions(true) as $action) {
$blockBody['form'] .= sprintf('<option value="%s">%s</option>',$action,$action);
}
$blockBody['form'] .= '</select><br />';
$blockBody['form'] .= '<input align="left" type="submit" name="submit" value="Go" />';
$blockBody['form'] .= sprintf('<input type="hidden" name="index" value="%s" />',$app['server']->getIndex());
$blockBody['form'] .= '</form>';
} else {
$mediawait = $summaryInfo->mediaActions();
$graph['mediawait']['total'] = 0;
$graph['mediawait']['count'] = 0;
$graph['thruput']['total'] = 0;
$graph['thruput']['count'] = 0;
$mode = array();
foreach ($_REQUEST['mediaactions'] as $action) {
if (isset($mediawait[$action]))
foreach ($mediawait[$action] as $index => $detail) {
$start = strtotime(tsmDate($detail['START_TIME'],'nomsec'));
$end = strtotime(tsmDate($detail['END_TIME'],'nosec'));
$graph['mediawait']['data'][$detail['ACTIVITY']][$end] = $detail['MEDIAW'];
$graph['mediawait']['total'] += $detail['MEDIAW'];
$graph['mediawait']['count']++;
@$mode[$detail['MEDIAW']]++;
$graph['thruput']['data'][$detail['ACTIVITY']][$end] = $detail['BYTES']/1024/($end+.1-$start);
}
# Drop the first and last entry
ksort($mode);
array_pop($mode);
$total = 0;
$counter = 0;
foreach ($mode as $index => $value) {
if ($counter) {
$total += $index * $value;
}
$counter++;
}
if ($counter)
$graph['mediawait']['mode'] = $total/$counter;
# Save Session
$_SESSION['graph'] = $graph;
# Media Wait Graph
$blockTitle['mediawait'] = sprintf(_('Migration Information for %s (%s) %s.%s.%s.%s'),
$app['server']->GetStatusDetail('SERVER_NAME'),
$app['server']->GetStatusDetail('PLATFORM'),
$app['server']->GetStatusDetail('VERSION'),
$app['server']->GetStatusDetail('RELEASE'),
$app['server']->GetStatusDetail('LEVEL'),
$app['server']->GetStatusDetail('SUBLEVEL'));
$blockBody['mediawait'] = '<table class="blockcitem">';
$blockBody['mediawait'] .= sprintf('<tr><th colspan=2 class="title">%s</th></tr>',_('Media Wait Graph'));
$blockBody['mediawait'] .= '<tr><td><table class="blockcitem" border=0>';
$blockBody['mediawait'] .= '<tr><td colspan=2>&nbsp;</td></tr>';
$blockBody['mediawait'] .= '</table></td>';
$blockBody['mediawait'] .= sprintf('<td align="right"><img src="image.server.stats.php?index=%s&activity=mediawait" /></td></tr>',
$app['server']->getIndex());
$blockBody['mediawait'] .= '</table>';
# Thruput Graph
$blockTitle['thruput'] = sprintf(_('Server Thruput for %s (%s) %s.%s.%s.%s'),
$app['server']->GetStatusDetail('SERVER_NAME'),
$app['server']->GetStatusDetail('PLATFORM'),
$app['server']->GetStatusDetail('VERSION'),
$app['server']->GetStatusDetail('RELEASE'),
$app['server']->GetStatusDetail('LEVEL'),
$app['server']->GetStatusDetail('SUBLEVEL'));
$blockBody['thruput'] = '<table class="blockcitem">';
$blockBody['thruput'] .= sprintf('<tr><th colspan=2 class="title">%s</th></tr>',_('Server Thruput Graph'));
$blockBody['thruput'] .= '<tr><td><table class="blockcitem" border=0>';
$blockBody['thruput'] .= '<tr><td colspan=2>&nbsp;</td></tr>';
$blockBody['thruput'] .= '</table></td>';
$blockBody['thruput'] .= sprintf('<td align="right"><img src="image.server.stats.php?index=%s&activity=thruput" /></td></tr>',
$app['server']->getIndex());
$blockBody['thruput'] .= '</table>';
}
}
# End
render_page($blockTitle,$blockBody);
?>

90
htdocs/show_cache.php Normal file
View File

@ -0,0 +1,90 @@
<?php
// $Header: /cvsroot/phptsmadmin/phpTSMadmin/htdocs/show_cache.php,v 1.4 2009/04/19 04:00:59 wurley Exp $
/**
* This script shows the contents of the cache for debugging purposes
*
* @package leenooksApp
*/
/**
*/
require './common.php';
$entry['key'] = get_request('key','REQUEST');
$entry['index'] = get_request('index','REQUEST');
if (isset($entry['index']) && isset($entry['key'])) {
list($entry['server'],$entry['x']) = split(':',$entry['index']);
debug_dump($_SESSION[$entry['key']][$entry['server']][$entry['x']],1);
}
if ($entry['key'])
debug_dump($_SESSION[$entry['key']],1);
if (! $_SESSION[APPCONFIG]->getValue('appearance','hide_debug_info')) {
echo '<div style="font-size: 11px"><ul>';
foreach (array_keys($_SESSION) as $key) {
if (($key == 'cache') && is_array($_SESSION[$key]))
foreach (array_keys($_SESSION['cache']) as $server) {
foreach (array_keys($_SESSION['cache'][$server]) as $x) {
$index = sprintf('%s:%s',$server,$x);
printf('<li><span id="%s"><a href="javascript:get(\'%s\',\'%s\');">%s</a></span><div id="%sloading" style="display: none" ></div></li>',
$key.$index,$key,$index,$key.'.'.$index,$key.$index,$key.$index);
}
}
else
printf('<li><span id="%s"><a href="javascript:get(\'%s\', \'\');">%s</a></span><div id="%sloading" style="display: none" ></div></li>',
$key,$key,$key,$key);
}
echo '</ul></div>';
}
?>
<script type="text/javascript" language="javascript">
var http_request = false;
var newtree_div;
var obj_key = '';
var obj_ind = '';
var obj = null;
function alertCacheContents(result) {
if (obj) {
obj.innerHTML = '<a href="javascript:close(\'' + obj_key + '\', \'' + obj_ind + '\')">' + obj_key + '.' + obj_ind + ' [close]<\/a>';
obj.innerHTML += result;
obj = null;
newtree_div.display = 'none';
}
}
function cancelCacheContents() {
if (obj) {
obj.innerHTML = '<a href="javascript:get(\'' + obj_key + '\', \'' + obj_ind + '\');">' + obj_key + '.' + obj_ind + '<\/a>';
newtree_div.display = 'none';
obj = null;
}
}
function get(key,xx) {
if (obj) cancelHttpRequest();
obj_key = key;
obj_ind = xx;
obj = document.getElementById(key + xx);
newtree_div = document.getElementById(key + xx + 'loading').style;
newtree_div.display = 'block';
var poststr = "cmd=show_cache&key=" + encodeURI(key);
if (xx) {
poststr += "&index=" + encodeURI(xx);
}
obj.innerHTML = '<img src="images/ajax-spinner.gif" /> Loading...';
makePOSTRequest('cmd.php',poststr,'alertCacheContents','cancelCacheContents');
}
function close(key,xx) {
document.getElementById(key + xx).innerHTML = '<a href="javascript:get(\'' + key + '\', \'' + xx + '\');">' + key + '.' + xx + '<\/a>';
}
</script>

189
htdocs/summary.gantt.php Normal file
View File

@ -0,0 +1,189 @@
<?php
// $Header: /cvsroot/phptsmadmin/phpTSMadmin/htdocs/summary.gantt.php,v 1.4 2009/04/19 04:00:59 wurley Exp $
# @todo: Hotlink the hostname to the detail script.
# Required Libraries
require './common.php';
$form['from'] = get_request('from','REQUEST',false,date('Y-m-d',time()-86400));
$form['to'] = get_request('to','REQUEST',false,date('Y-m-d'));
# Defaults
$reportEnd = strftime('%Y-%m-%d 23:59',time());
$reportStart = strftime('%Y-%m-%d 00:00',time()-86400);
$summaryInfo = objectCache('summaryinfo');
# List of Clients.
$blockTitle['node'] = sprintf(_('Select DATE RANGE on %s'),$app['server']->getValue('server','name'));
$blockBody['node'] = '<form action="cmd.php">';
$blockBody['node'] .= '<input type="hidden" name="cmd" value="summary.gantt" />';
$blockBody['node'] .= sprintf('<input type="hidden" name="index" value="%s" />',$app['server']->getIndex());
$blockBody['node'] .= 'From ';
$blockBody['node'] .= '<select name="from">';
foreach ($summaryInfo->getSummaryRange() as $date) {
$blockBody['node'] .= sprintf('<option id="%s" %s>%s</option>',
$date,
$date == $form['from'] ? 'selected' : '',
$date);
}
$blockBody['node'] .= '</select>';
$blockBody['node'] .= '&nbsp;';
$blockBody['node'] .= 'To ';
$blockBody['node'] .= '<select name="to">';
foreach ($summaryInfo->getSummaryRange() as $date) {
$blockBody['node'] .= sprintf('<option id="%s" %s>%s</option>',
$date,
$date == $form['to'] ? 'selected' : '',
$date);
}
$blockBody['node'] .= '</select>';
$blockBody['node'] .= '<input align="left" type="submit" name="submit" value="Go" />';
$blockBody['node'] .= '</form>';
if ($form['from'] && $form['to']) {
initJPGraph(true);
# A new graph with automatic size
$graph = new GanttGraph(0,0,'auto');
# A new activity on row '0'
$item = 0;
foreach ($summaryInfo->getSummary($form['from'],$form['to']) as $tsmActivity) {
$tsmCaption = '';
$tsmCSIM = '';
$waiting = 0;
$timestart = preg_replace('/(.*:.*):.*/','$1',$tsmActivity['START_TIME']);
$timeend = preg_replace('/(.*:.*):.*/','$1',$tsmActivity['END_TIME']);
$timeseconds = strtotime(preg_replace('/([0-9])\..*$/','$1',$tsmActivity['END_TIME'])) -
strtotime(preg_replace('/([0-9])\..*$/','$1',$tsmActivity['START_TIME']));
if ($timeseconds) {
$waiting = $tsmActivity['MEDIAW']/$timeseconds;
}
# It seems sometimes, the MEDIAW time can be larger than the activity time?
if ($waiting > 1) $waiting = 1;
$priority = 10;
switch ($tsmActivity['ACTIVITY']) {
case('TAPE MOUNT'):
$summary = $tsmActivity['ACTIVITY'].' ('.$tsmActivity['DRIVE_NAME'].')';
$tsmCSIM = sprintf('%s (%s)',$tsmActivity['VOLUME_NAME'],$tsmActivity['LAST_USE']);
$priority = 1;
break;
case('STGPOOL BACKUP'):
$summary = $tsmActivity['ACTIVITY'].' ('.$tsmActivity['ENTITY'].')';
$tsmCSIM = sprintf('%3d MB. %ss Media wait',$tsmActivity['BYTES']/1024/1024,$tsmActivity['MEDIAW']);
$priority = 4;
break;
case('ARCHIVE'):
$summary = $tsmActivity['ACTIVITY'].' ('.$tsmActivity['ENTITY'].')';
$tsmCSIM = sprintf('%3d MB',$tsmActivity['BYTES']/1024/1024);
$priority = 3;
break;
case('BACKUP'):
$summary = $tsmActivity['ACTIVITY'].' ('.$tsmActivity['ENTITY'].')';
$tsmCSIM = sprintf('%3d MB',$tsmActivity['BYTES']/1024/1024);
$priority = 2;
break;
case('RESTORE'):
$summary = $tsmActivity['ACTIVITY'].' ('.$tsmActivity['ENTITY'].')';
$tsmCSIM = sprintf('%3d MB. %ss Media wait',$tsmActivity['BYTES']/1024/1024,$tsmActivity['MEDIAW']);
$priority = 2;
break;
case('FULL_DBBACKUP'):
$summary = $tsmActivity['ACTIVITY'];
$tsmCSIM = sprintf('%3d MB. %ss Media wait',$tsmActivity['BYTES']/1024/1024,$tsmActivity['MEDIAW']);
break;
case('RECLAMATION'):
$summary = $tsmActivity['ACTIVITY'].' ('.preg_replace('/^(.*)\s+\(.*\)$/','$1',$tsmActivity['ENTITY']).')';
$tsmCSIM = sprintf('%3d MB. %ss Media wait',$tsmActivity['BYTES']/1024/1024,$tsmActivity['MEDIAW']);
$priority = 4;
break;
case('MIGRATION'):
$summary = $tsmActivity['ACTIVITY'].' ('.$tsmActivity['ENTITY'].')';
$tsmCSIM = sprintf('%3d MB. %ss Media wait',$tsmActivity['BYTES']/1024/1024,$tsmActivity['MEDIAW']);
$priority = 4;
break;
case('MOVE NODEDATA'):
$summary = $tsmActivity['ACTIVITY'].' ('.$tsmActivity['ENTITY'].')';
$tsmCSIM = sprintf('%3d MB. %ss Media wait',$tsmActivity['BYTES']/1024/1024,$tsmActivity['MEDIAW']);
$priority = 4;
break;
case('EXPIRATION'):
$summary = 'EXPIRATION PROCESSING';
$tsmCaption = sprintf('%ss',$tsmActivity['AFFECTED']);
default: $summary = $tsmActivity['ACTIVITY'];
}
$lineitems[$summary][$item]['wait'] = $waiting;
$lineitems[$summary][$item]['summary'] = $summary;
$lineitems[$summary][$item]['start'] = $timestart;
$lineitems[$summary][$item]['end'] = $timeend;
$lineitems[$summary][$item]['csim'] = $tsmCSIM;
$lineitems[$summary][$item]['caption'] = $tsmCaption;
$lineitems[$summary]['priority'] = $priority;
$lineitems[$summary]['summary'] = $summary;
$item++;
}
if ($lineitems) {
masort($lineitems,'priority,summary',1);
$item=0;
foreach ($lineitems as $lineitem => $linedetails) {
# Put a gap between our priority items.
if ($item && ($lastPriority <> $linedetails['priority']))
$item++;
foreach ($linedetails as $eventdetails) {
if (! is_array($eventdetails)) continue;
$activity = new GanttBar($item,$eventdetails['summary'],$eventdetails['start'],$eventdetails['end']);
$activity->progress->Set($eventdetails['wait']);
$activity->caption ->Set($eventdetails['caption']);
$activity->SetCSIMTarget('#',($eventdetails['csim'] ? $eventdetails['csim'] : 'NoCSIM'));
$activity->title->SetCSIMTarget('#',($eventdetails['csim'] ? $eventdetails['csim'] : 'NoCSIM'));
$graph->Add($activity);
}
$item++;
$lastPriority = $linedetails['priority'];
}
$graph->SetMarginColor('#eeeeff');
$graph->SetFrame(true,'#eeeeff',0);
// We want to display day, hour and minute scales
$graph->ShowHeaders(GANTT_HDAY | GANTT_HHOUR | GANTT_HMIN);
$graph->hgrid->Show();
$graph->hgrid->SetRowFillColor('darkred@0.85');
// Setup hour format
$graph->scale->hour->SetIntervall(1);
$graph->scale->hour->SetStyle(HOURSTYLE_H24);
$graph->scale->minute->SetIntervall(30);
$graph->scale->dividerh->SetWeight(3);
$graph->scale->dividerh->SetColor('navy');
// Display the Gantt chart
$imageFile = sprintf('%s/gantt.summary.%s.png',realpath($_SESSION[APPCONFIG]->getValue('image','path')),$app['server']->getIndex());
$imageHTML = sprintf('%sgantt.summary.%s.png',$_SESSION[APPCONFIG]->getValue('image','pathurl'),$app['server']->getIndex());
$graph->Stroke($imageFile);
} else {
# @todo: Nice message about no data.
}
$blockTitle['gantt'] = sprintf(_('Activity Summary for server %s'),$app['server']->getValue('server','name'));
$blockBody['gantt'] = '<table class="result"><tr><td>';
$blockBody['gantt'] .= $graph->GetHTMLImageMap('gantt.summary');
$blockBody['gantt'] .= sprintf('<img src="%s" ISMAP USEMAP="#gantt.summary" border=0 />',$imageHTML,$app['server']->getIndex()) ;
$blockBody['gantt'] .= '</td></tr></table>';
}
# End
render_page($blockTitle,$blockBody);
?>

160
htdocs/volume.info.php Normal file
View File

@ -0,0 +1,160 @@
<?php
// $Header: /cvsroot/phptsmadmin/phpTSMadmin/htdocs/volume.info.php,v 1.21 2009/04/19 04:57:32 wurley Exp $
# Required Libraries
require './common.php';
# Defaults
$volumes = objectCache('volumes');
$blockTitle['volinfo'] = 'Volume(s) that may need attention';
$blockBody['volinfo'] = '<br /><table class="result_table" border=0>';
$blockBody['volinfo'] .= '<tr><td class="heading">Library</td><td class="heading">Slot</td><td class="heading">Barcode/Vol Name</td><td class="heading">Usage</td><td class="heading">Status/Access</td><td class="heading">Library Access</td><td class="heading">Utilisation</td><td class="heading">Reclaim</td><td class="heading">Last Read</td><td class="heading">Last Write</td></tr>';
# The following COPY VOLUMES in the library can be checked out.
if (count($volumes->libCopyVolumes(true))) {
$blockBody['volinfo'] .= sprintf('<tr><td colspan=0><b>%s</b></td></tr>',_('The following COPY pool volumes can be checked out of the library(s).'));
$counter = 0;
foreach ($volumes->libCopyVolumes(true) as $volume) {
$blockBody['volinfo'] .= sprintf('<tr class="%s"><td>%s</td><td>%s</td><td>%s</td><td>%s</td><td>%s/%s</td><td>%s</td><td>%s%%</td><td>%s%%</td><td>%s</td><td>%s</td></tr>',
$counter++%2 ? 'even' : 'odd',
$volume->lib['name'],
isset($volume->location) ? $volume->location : 'InLIB',
$volume->getName(),
$volume->stgpool,
$volume->status['volume'],
$volume->access,
'N/A',
$volume->utilisation,
$volume->reclaim,
tsmDate($volume->last['read'],'notime'),tsmDate($volume->last['write'],'notime'));
}
$blockBody['volinfo'] .= '<tr><td colspan=0>&nbsp;</td></tr>';
}
# Non-Read/Write Volumes that need to be fixed.
if (count($volumes->nonReadWriteVolumes())) {
$blockBody['volinfo'] .= sprintf('<tr><td colspan=0><b>%s</b></td></tr>',_('NON READ/WRITE volumes that need to be addressed.'));
$counter = 0;
foreach ($volumes->nonReadWriteVolumes() as $volume) {
$blockBody['volinfo'] .= sprintf('<tr class="%s"><td>%s</td><td>%s</td><td>%s</td><td>%s</td><td>%s/%s</td><td>%s</td><td>%s%%</td><td>%s%%</td><td>%s</td><td>%s</td></tr>',
$counter++%2 ? 'even' : 'odd',
isset($volume->lib['name']) ? $volume->lib['name'] : '&nbsp;',
isset($volume->location) ? $volume->location : 'InLIB',
$volume->name,
$volume->stgpool,
$volume->status['volume'],
$volume->access,
'N/A',
$volume->utilisation,
$volume->reclaim,
tsmDate($volume->last['read'],'notime'),tsmDate($volume->last['write'],'notime'));
}
$blockBody['volinfo'] .= '<tr><td colspan=0>&nbsp;</td></tr>';
}
# Non-Read/Write Volumes that need to be fixed.
if (count($volumes->reclaimVolumes())) {
$blockBody['volinfo'] .= sprintf('<tr><td colspan=0><b>%s</b></td></tr>',_('The following volumes should be RECLAIMed (automatically).'));
$counter = 0;
foreach ($volumes->reclaimVolumes() as $volume) {
$blockBody['volinfo'] .= sprintf('<tr class="%s"><td>%s</td><td>%s</td><td>%s</td><td>%s</td><td>%s/%s</td><td>%s</td><td>%s%%</td><td>%s%%</td><td>%s</td><td>%s</td></tr>',
$counter++%2 ? 'even' : 'odd',
isset($volume->lib['name']) ? $volume->lib['name'] : '&nbsp;',
isset($volume->location) ? $volume->location : 'InLIB',
$volume->getName(),
$volume->stgpool,
$volume->status['volume'],
$volume->access,
'N/A',
$volume->utilisation,
$volume->reclaim,
tsmDate($volume->last['read'],'notime'),tsmDate($volume->last['write'],'notime'));
}
$blockBody['volinfo'] .= '<tr><td colspan=0>&nbsp;</td></tr>';
}
# Following volumes have had errors.
if (count($volumes->errorVolumes())) {
$blockBody['volinfo'] .= sprintf('<tr><td colspan=0><b>%s</b></td></tr>',_('The following volumes have had ERRORS.'));
$counter = 0;
foreach ($volumes->errorVolumes() as $volume) {
$blockBody['volinfo'] .= sprintf('<tr class="%s"><td>%s</td><td>%s</td><td>%s</td><td>%s</td><td>%s/%s</td><td>%s</td><td>%s%%</td><td>%s%%</td><td>%s (%s)</td><td>%s (%s)</td></tr>',
$counter++%2 ? 'even' : 'odd',
isset($volume->lib['name']) ? $volume->lib['name'] : '&nbsp;',
isset($volume->location) ? $volume->location : 'InLIB',
$volume->name,
$volume->stgpool,
$volume->status['volume'],
$volume->access,
'N/A',
$volume->utilisation,
$volume->reclaim,
tsmDate($volume->last['read'],'notime'),$volume->error['read'],
tsmDate($volume->last['write'],'notime'),$volume->error['write']);
}
$blockBody['volinfo'] .= '<tr><td colspan=0>&nbsp;</td></tr>';
}
# Following volumes have not been read/written to for a long time.
if (count($volumes->staleVolumes($app['server']->getValue('system','tapeage')))) {
$blockBody['volinfo'] .= sprintf('<tr><td colspan=0><b>%s</b></td></tr>',sprintf(_('The following volumes have NOT been read/written to for %s days.'),$app['server']->getValue('system','tapeage')));
$counter = 0;
foreach ($volumes->staleVolumes($app['server']->getValue('system','tapeage')) as $volume) {
$blockBody['volinfo'] .= sprintf('<tr class="%s"><td>%s</td><td>%s</td><td>%s</td><td>%s</td><td>%s/%s</td><td>%s</td><td>%s%%</td><td>%s%%</td><td>%s</td><td>%s</td></tr>',
$counter++%2 ? 'even' : 'odd',
isset($volume->lib['name']) ? $volume->lib['name'] : '&nbsp;',
isset($volume->location) ? $volume->location : 'InLIB',
$volume->getName(),
$volume->stgpool,
$volume->status['volume'],
$volume->access,
'N/A',
$volume->utilisation,
$volume->reclaim,
tsmDate($volume->last['read'],'notime'),tsmDate($volume->last['write'],'notime'));
}
$blockBody['volinfo'] .= '<tr><td colspan=0>&nbsp;</td></tr>';
}
# Following volumes are empty or pending.
if (count($volumes->pendingVolumes()) || count($volumes->emptyVolumes())) {
$blockBody['volinfo'] .= sprintf('<tr><td colspan=0><b>%s</b></td></tr>',_('The following volumes are either EMPTY or PENDING.'));
$counter = 0;
foreach ($volumes->pendingVolumes() as $volume) {
$blockBody['volinfo'] .= sprintf('<tr class="%s"><td>%s</td><td>%s</td><td>%s</td><td>%s</td><td><acronym title="Pending: %s Avail: %s">%s</acronym>/%s</td><td>%s</td><td>%s%%</td><td>%s%%</td><td>%s</td><td>%s</td></tr>',
$counter++%2 ? 'even' : 'odd',
isset($volume->lib['name']) ? $volume->lib['name'] : '&nbsp;',
isset($volume->location) ? $volume->location : 'InLIB',
$volume->name,
$volume->stgpool,
tsmDate($volume->pending['start'],'notime'),tsmDate($volume->pending['end'],'notime'),
$volume->status['volume'],
$volume->access,
'N/A',
$volume->utilisation,
$volume->reclaim,
tsmDate($volume->last['read'],'notime'),tsmDate($volume->last['write'],'notime'));
}
$counter = 0;
foreach ($volumes->emptyVolumes() as $volume) {
$blockBody['volinfo'] .= sprintf('<tr class="%s"><td>%s</td><td>%s</td><td>%s</td><td>%s</td><td>%s/%s</td><td>%s</td><td>%s%%</td><td>%s%%</td><td>%s</td><td>%s</td></tr>',
$counter++%2 ? 'even' : 'odd',
isset($volume->lib['name']) ? $volume->lib['name'] : '&nbsp;',
isset($volume->location) ? $volume->location : 'InLIB',
$volume->getName(),
$volume->stgpool,
$volume->status['volume'],
$volume->access,
'N/A',
$volume->utilisation,
$volume->reclaim,
tsmDate($volume->last['read'],'notime'),tsmDate($volume->last['write'],'notime'));
}
}
$blockBody['volinfo'] .= '</table>';
# End
render_page($blockTitle,$blockBody);
?>

View File

@ -0,0 +1,95 @@
<?php
// $Header: /cvsroot/phptsmadmin/phpTSMadmin/htdocs/volume.inventory.php,v 1.11 2008/08/19 11:06:50 wurley Exp $
# Required Libraries
require './common.php';
# Defaults
$libraries = objectCache('libraries');
$libvolumes = objectCache('volumes');
# The following VOLUMES in the library can be checked out.
$blockTitle['innotci'] = 'Volume Inventory Summary.';
$blockBody['innotci'] = '<table class="result_table" width=100% border=0>';
$blockBody['innotci'] .= '<tr><td class="heading">Library</td><td class="heading">Slot</td><td class="heading">Barcode/Vol Name</td><td class="heading">Usage</td><td class="heading">Status/Access</td><td class="heading">Library Access</td><td class="heading">Utilisation</td><td class="heading">Reclaim</td><td class="heading">Last Read</td><td class="heading">Last Write</td></tr>';
$blockBody['innotci'] .= sprintf('<tr><td colspan=0><b>%s</b></td></tr>',_('The following volumes are in a library, but NOT checked in.'));
$counter = 0;
foreach ($libraries->libVolumes(false) as $library => $volumes) {
foreach ($volumes as $element => $volume) {
$blockBody['innotci'] .= sprintf('<tr class="%s"><td>%s</td><td>%s</td><td>%s</td><td>%s</td><td>%s/%s</td><td>%s</td><td>%s%%</td><td>%s%%</td><td>%s</td><td>%s</td></tr>',
$counter++%2 ? 'even' : 'odd',
isset($volume->lib['name']) ? $volume->lib['name'] : 'Unknown LIB',
isset($volume->location) ? $volume->location : $volume->lib['slot'],
$volume->name,
$volume->stgpool,
$volume->status['volume'],
$volume->access,
isset($volume->lib['access']) ? $volume->lib['access'] : 'N/A',
$volume->utilisation,
$volume->reclaim,
tsmDate($volume->last['read'],'notime'),tsmDate($volume->last['write'],'notime'));
}
}
$blockBody['innotci'] .= '<tr><td colspan=0>&nbsp;</td></tr>';
# The following PRIMARY VOLUMES not in the library.
$blockBody['innotci'] .= sprintf('<tr><td colspan=0><b>%s</b></td></tr>',_('The following PRIMARY pool volumes are NOT checked in a library.'));
$counter = 0;
foreach ($libvolumes->primaryNotInLib() as $volume) {
$blockBody['innotci'] .= sprintf('<tr class="%s"><td>%s</td><td>%s</td><td>%s</td><td>%s</td><td>%s/%s</td><td>%s</td><td>%s%%</td><td>%s%%</td><td>%s</td><td>%s</td></tr>',
$counter++%2 ? 'even' : 'odd',
'N/A',
isset($volume->location) ? $volume->location : 'InLIB',
$volume->getName(),
$volume->stgpool,
$volume->status['volume'],
$volume->access,
'N/A',
$volume->utilisation,
$volume->reclaim,
tsmDate($volume->last['read'],'notime'),tsmDate($volume->last['write'],'notime'));
}
$blockBody['innotci'] .= '<tr><td colspan=0>&nbsp;</td></tr>';
# The following COPY VOLUMES in the library can be checked out.
$blockBody['innotci'] .= sprintf('<tr><td colspan=0><b>%s</b></td></tr>',_('The following COPY pool volumes can be checked out of the library(s).'));
$counter = 0;
foreach ($libvolumes->libCopyVolumes(true) as $volume) {
$blockBody['innotci'] .= sprintf('<tr class="%s"><td>%s</td><td>%s</td><td>%s</td><td>%s</td><td>%s/%s</td><td>%s</td><td>%s%%</td><td>%s%%</td><td>%s</td><td>%s</td></tr>',
$counter++%2 ? 'even' : 'odd',
$volume->lib['name'],
isset($volume->location) ? $volume->location : 'InLIB',
$volume->getName(),
$volume->stgpool,
$volume->status['volume'],
$volume->access,
'N/A',
$volume->utilisation,
$volume->reclaim,
tsmDate($volume->last['read'],'notime'),tsmDate($volume->last['write'],'notime'));
}
$blockBody['innotci'] .= '<tr><td colspan=0>&nbsp;</td></tr>';
# The following PRIMARY VOLUMES not in the library.
$blockBody['innotci'] .= sprintf('<tr><td colspan=0><b>%s</b></td></tr>',_('The following COPY pool volumes are not checked in a library.'));
$counter = 0;
foreach ($libvolumes->libCopyVolumes(false) as $volume) {
$blockBody['innotci'] .= sprintf('<tr class="%s"><td>%s</td><td>%s</td><td>%s</td><td>%s</td><td>%s/%s</td><td>%s</td><td>%s%%</td><td>%s%%</td><td>%s</td><td>%s</td></tr>',
$counter++%2 ? 'even' : 'odd',
'N/A',
isset($volume->location) ? $volume->location : 'InLIB',
$volume->getName(),
$volume->stgpool,
$volume->status['volume'],
$volume->access,
'N/A',
$volume->utilisation,
$volume->reclaim,
tsmDate($volume->last['read'],'notime'),tsmDate($volume->last['write'],'notime'));
}
$blockBody['innotci'] .= '</table>';
# End
render_page($blockTitle,$blockBody);
?>

11
index.php Normal file
View File

@ -0,0 +1,11 @@
<?php
// $Header: /cvsroot/phptsmadmin/phpTSMadmin/index.php,v 1.3 2008/01/13 08:42:37 wurley Exp $
/**
* @package leenooksApp
*/
# You should secure your application by making the htdocs/ your docroot.
header('Location: htdocs/index.php');
die();
?>

283
lib/common.php Normal file
View File

@ -0,0 +1,283 @@
<?php
// $Header: /cvsroot/phptsmadmin/phpTSMadmin/lib/common.php,v 1.18 2009/04/19 04:12:19 wurley Exp $
/**
* Contains code to be executed at the top of each application page.
* include this file at the top of every PHP file.
*
* This file will "pre-initialise" an application environment so that any PHP file will have a consistent
* environment with other application PHP files.
*
* This code WILL NOT check that all required functions are usable/readable, etc. This process has
* been moved to index.php (which really is only called once when a browser hits the application for the first time).
*
* @author Deon George (c) 2009
* @package phpTSMadmin
*/
/**
* @package phpTSMadmin
*/
/* Initialize the app array. The app array is initialised each invocation of a PLA script and therefore
has no state between invocations.*/
$app = array();
# The index we will store our config in $_SESSION
if (! defined('APPCONFIG'))
define('APPCONFIG','appConfig');
/**
* Catch any scripts that are called directly.
* If they are called directly, then they should be routed back through index.php
*/
$app['direct_scripts'] = array('cmd.php','index.php',
'image.dbbackuphistory.php','image.occupancy.php','image.backupevents.php','image.schedule.gantt.php'
);
# Which script was invoked.
$app['script_running'] = $_SERVER['SCRIPT_NAME'];
foreach ($app['direct_scripts'] as $script) {
$app['scriptOK'] = false;
if (preg_match('/'.$script.'$/',$app['script_running'])) {
$app['scriptOK'] = true;
break;
}
}
# Anything in the tools dir or cron dir can be executed directly.
if ((! $app['scriptOK'] && preg_match('/^\/[cron|tools]/',$app['script_running'])) || ! isset($_SERVER['SERVER_SOFTWARE']))
$app['scriptOK'] = true;
if (! $app['scriptOK']) {
if (isset($_REQUEST['server_id']))
header(sprintf('Location: index.php?server_id=%s',$_REQUEST['server_id']));
else
header('Location: index.php');
die();
}
/**
* All commands are disabled in read-only unless specified here
*/
$app['readwrite_cmds'] = array(
);
/**
* Timer stopwatch, used to instrument the application
*/
if (! function_exists('stopwatch')) {
function stopwatch() {
static $mt_previous = 0;
list($usec,$sec) = explode(' ',microtime());
$mt_current = (float)$usec + (float)$sec;
if (! $mt_previous) {
$mt_previous = $mt_current;
return 0;
} else {
$mt_diff = ($mt_current - $mt_previous);
$mt_previous = $mt_current;
return sprintf('%.5f',$mt_diff);
}
}
# For compatability - if common has been sourced a second time, then return to the calling script.
} else {
return;
}
# Set the defualt time zone, if it isnt set in php.ini
if (function_exists('date_default_timezone_set') && ! ini_get('date.timezone'))
date_default_timezone_set('UTC');
# If we are called from index.php, LIBDIR will be set, all other calls to common.php dont need to set it.
if (! defined('LIBDIR'))
define('LIBDIR','../lib/');
# For PHP5 backward/forward compatibility
if (! defined('E_STRICT'))
define('E_STRICT',2048);
# General functions needed to proceed.
ob_start();
require_once realpath(LIBDIR.'functions.php');
if (ob_get_level())
ob_end_clean();
/**
* Turn on all notices and warnings. This helps us write cleaner code (we hope at least)
* Our custom error handler receives all error notices that pass the error_reporting()
* level set above.
*/
# Call our custom defined error handler, if it is defined in functions.php
if (function_exists('app_error_handler'))
set_error_handler('app_error_handler');
# Disable error reporting until all our required functions are loaded.
error_reporting(0);
/**
* functions.php should have defined our $app['function_files'] array, listing all our
* required functions (order IS important).
* index.php should have checked they exist and are usable - we'll assume that the user
* has been via index.php, and fixed any problems already.
*/
ob_start();
if (isset($app['function_files']) && is_array($app['function_files']))
foreach ($app['function_files'] as $script)
require_once realpath($script);
# Now read in config_default.php
require_once realpath(LIBDIR.'config_default.php');
if (ob_get_level())
ob_end_clean();
# We are now ready for error reporting.
error_reporting(E_ALL);
# Start our session.
app_session_start();
# If we get here, and $_SESSION[APPCONFIG] is not set, then redirect the user to the index.
if (isset($_SERVER['SERVER_SOFTWARE']) && ! isset($_SESSION[APPCONFIG])) {
if ($_SERVER['QUERY_STRING'])
header(sprintf('Location: index.php?URI=%s',base64_encode($_SERVER['QUERY_STRING'])));
else
header('Location: index.php');
die();
} else {
# Check our custom variables.
# @todo Change this so that we dont process a cached session.
$_SESSION[APPCONFIG]->CheckCustom();
}
# Check for safe mode.
if (ini_get('safe_mode') && ! get_request('cmd','GET'))
system_message(array(
'title'=>_('PHP Safe Mode'),
'body'=>_('You have PHP Safe Mode enabled. This application may work unexpectedly in Safe Mode.'),
'type'=>'info'));
# Set our timezone, if it is specified in config.php
if ($_SESSION[APPCONFIG]->getValue('appearance','timezone'))
date_default_timezone_set($_SESSION[APPCONFIG]->getValue('appearance','timezone'));
# If we are here, $_SESSION is set - so enabled DEBUGing if it has been configured.
if (($_SESSION[APPCONFIG]->getValue('debug','syslog') || $_SESSION[APPCONFIG]->getValue('debug','file'))
&& $_SESSION[APPCONFIG]->getValue('debug','level'))
define('DEBUG_ENABLED',1);
else
define('DEBUG_ENABLED',0);
if (DEBUG_ENABLED)
debug_log('Application (%s) initialised and starting with (%s).',1,__FILE__,__LINE__,__METHOD__,
app_version(),$_REQUEST);
# Set our PHP timelimit.
if ($_SESSION[APPCONFIG]->getValue('session','timelimit') && ! ini_get('safe_mode'))
set_time_limit($_SESSION[APPCONFIG]->getValue('session','timelimit'));
# If debug mode is set, increase the time_limit, since we probably need it.
if (DEBUG_ENABLED && $_SESSION[APPCONFIG]->getValue('session','timelimit') && ! ini_get('safe_mode'))
set_time_limit($_SESSION[APPCONFIG]->getValue('session','timelimit') * 5);
/**
* Language configuration. Auto or specified?
* Shall we attempt to auto-determine the language?
*/
# If we are in safe mode, and LANG is not in the allowed vars, display an error.
if (ini_get('safe_mode') && ! in_array('LANG',explode(',',ini_get('safe_mode_allowed_env_vars'))))
error('You are running in SAFE_MODE, but LANG is not in the safe_mode_allowed_env_vars. Please add LANG to safe_mode_allowed_env_vars','error',true,false);
$app['language'] = $_SESSION[APPCONFIG]->getValue('appearance','language');
if ($app['language'] == 'auto') {
# Make sure their browser correctly reports language. If not, skip this.
if (isset($_SERVER['HTTP_ACCEPT_LANGUAGE'])) {
# Get the languages which are spetcified in the HTTP header
$app['lang_http'] = preg_split ('/[;,]+/',$_SERVER['HTTP_ACCEPT_LANGUAGE']);
foreach ($app['lang_http'] as $key => $value) {
if (substr($value,0,2) == 'q=') {
unset($app['lang_http'][$key]);
continue;
}
$value = preg_split('/[-]+/',$value);
if (sizeof($value) == 2)
$app['lang_http'][$key] = strtolower($value[0]).'_'.strtoupper($value[1]);
else
$app['lang_http'][$key] = auto_lang(strtolower($value[0]));
}
$app['lang_http'] = array_unique($app['lang_http']);
foreach ($app['lang_http'] as $lang) {
$app['language_dir'] = LANGDIR.$lang;
if ((substr($lang,0,2) == 'en') ||
(file_exists($app['language_dir']) && is_readable($app['language_dir']))) {
# Set language
putenv('LANG='.$lang); # e.g. LANG=de_DE
$lang .= '.UTF-8';
setlocale(LC_ALL,$lang); # set LC_ALL to de_DE
bindtextdomain('messages',LANGDIR);
bind_textdomain_codeset('messages','UTF-8');
textdomain('messages');
header('Content-type: text/html; charset=UTF-8',true);
break;
}
}
#todo Generate an error if language doesnt exist.
}
} else {
# Grab the language file configured in config.php
#todo Generate an error if language doesnt exist.
if ($app['language'] != null) {
if (strcmp($app['language'],'english') == 0)
$app['language'] = 'en_GB';
# Set language
putenv('LANG='.$app['language']); # e.g. LANG=de_DE
$app['language'] .= '.UTF-8';
setlocale(LC_ALL,$app['language']); # set LC_ALL to de_DE
bindtextdomain('messages',LANGDIR);
bind_textdomain_codeset('messages','UTF-8');
textdomain('messages');
header('Content-type: text/html; charset=UTF-8',true);
}
}
/**
* Strip slashes from GET, POST, and COOKIE variables if this
* PHP install is configured to automatically addslashes()
*/
if (get_magic_quotes_gpc() && (! isset($slashes_stripped) || ! $slashes_stripped)) {
array_stripslashes($_REQUEST);
array_stripslashes($_GET);
array_stripslashes($_POST);
array_stripslashes($_COOKIE);
$slashes_stripped = true;
}
# Create our application repository variable.
$app['server'] = $_SESSION[APPCONFIG]->getServer(get_request('server_id','REQUEST'));
/**
* At this point we have read all our additional function PHP files and our configuration.
* If we are using hooks, run the session_init hook.
*/
if (function_exists('run_hook'))
run_hook('post_session_init',array());
?>

75
lib/config_custom.php Normal file
View File

@ -0,0 +1,75 @@
<?php
// $Header: /cvsroot/phptsmadmin/phpTSMadmin/lib/config_custom.php,v 1.3 2009/04/19 05:32:12 wurley Exp $
/**
* Custom Configuration processing and defaults.
*
* @author The phpTSMadmin development team
* @package phpTSMadmin
*/
/** Available Commands
*/
$config->configDefinition('command','devclassinfo',array(
'summary'=>'Device Class Info',
'desc'=>'This will show detailed information on your devclasses.',
'default'=>'devclass.info'));
$config->configDefinition('command','help',array(
'summary'=>'Help',
'desc'=>'Help Pages',
'default'=>'help'));
$config->configDefinition('command','libraryinfo',array(
'summary'=>'Library Info',
'desc'=>'Information on Automated Tape Libraries.',
'default'=>'library.info'));
$config->configDefinition('command','nodedetail',array(
'summary'=>'Node Detail',
'desc'=>'Detail of Node Storage Usage.',
'default'=>'node.detail'));
$config->configDefinition('command','nodeoccupancy',array(
'summary'=>'Node Occupancy',
'desc'=>'Summary of Node Occupancy.',
'default'=>'node.occupancy'));
$config->configDefinition('command','nodesummary',array(
'summary'=>'Node Summary',
'desc'=>'Summary of Node activities.',
'default'=>'node.summary'));
$config->configDefinition('command','nodethruput',array(
'summary'=>'Node Traffic',
'desc'=>'This will show recent node traffic.',
'default'=>'node.thruput'));
$config->configDefinition('command','schedulegantt',array(
'summary'=>'Schedule Gantt',
'desc'=>'Gantt view of todays schedules.',
'default'=>'schedule.gantt'));
$config->configDefinition('command','summarygantt',array(
'summary'=>'Activity Summary Gantt',
'desc'=>'Gantt view of todays activities.',
'default'=>'summary.gantt'));
$config->configDefinition('command','serverdb',array(
'summary'=>'Server DB Information',
'desc'=>'Database Information for TSM Server.',
'default'=>'server.db'));
$config->configDefinition('command','serverstats',array(
'summary'=>'Server Stats',
'desc'=>'TSM Server Performance Stats.',
'default'=>'server.stats'));
$config->configDefinition('command','volumeinfo',array(
'summary'=>'Volume Status',
'desc'=>'Status Information on Sequential Volumes.',
'default'=>'volume.info'));
$config->configDefinition('command','volumeinventory',array(
'summary'=>'Volume Inventory',
'desc'=>'Information on Volumes.',
'default'=>'volume.inventory'));
$config->configDefinition('lib','jpgraph',array(
'desc'=>'Path to JPGraph',
'default'=>LIBDIR.'JpGraph'));
$config->configDefinition('image','path',array(
'desc'=>'Path to generated images',
'default'=>HTDOCDIR.'tmp'));
$config->configDefinition('image','pathurl',array(
'desc'=>'URL Path to generated images',
'default'=>'tmp/'));
?>

337
lib/config_default.php Normal file
View File

@ -0,0 +1,337 @@
<?php
// $Header: /cvsroot/phptsmadmin/phpTSMadmin/lib/config_default.php,v 1.16 2009/04/19 05:44:55 wurley Exp $
/**
* Configuration processing and defaults.
*
* @author The phpTSMadmin development team
* @package phpTSMadmin
*
* @todo Add validation of set variables to enforce limits or particular values.
*/
/** The minimum version of PHP required to run this application. */
define('REQUIRED_PHP_VERSION','5.0.0');
/**
* The config class contains all our configuration settings for a session.
*
* An instance of this class should be stored in $_SESSION to maintain state, and to avoid
* rebuilding/rereading it at the state of each page output.
*
* @package phpTSMadmin
*
* @author The phpTSMadmin development team
* @author Deon George
*/
class Config {
public $custom;
protected $default;
public $servers = array();
public $hooks = array();
public function __construct() {
$this->custom = new stdClass;
$this->default = new stdClass;
$this->default->app['name'] = array(
'desc'=>'Application Name',
'default'=>'phpTSMadmin');
$this->default->appearance['compress'] = array(
'desc'=>'Compress Output',
'default'=>false);
$this->default->appearance['control_icons'] = array(
'desc'=>'Show the control as icons or text',
'default'=>false);
$this->default->appearance['menu'] = array(
'desc'=>'Class name which inherits from Menu class and implements the draw() method',
'default'=>'menu_html');
/** Language
* The language setting. If you set this to 'auto', This application will
* attempt to determine your language automatically. Otherwise, set
* this to your applicable language in xx_XX format.
*/
$this->default->appearance['language'] = array(
'desc'=>'Language',
'default'=>'auto');
$this->default->appearance['page_title'] = array(
'desc'=>'Change the page title to this text',
'default'=>'');
$this->default->appearance['stylesheet'] = array(
'desc'=>'Style sheet to use',
'default'=>'style.css');
$this->default->appearance['timezone'] = array(
'desc'=>'Define our timezone, if not defined in php.ini',
'default'=>null);
$this->default->appearance['logged_in_chars'] = array(
'desc'=>'Number of chars of loggin name to show',
'default'=>15);
/** Caching
*/
$this->default->cache['menu'] = array(
'desc'=>'Cache the Menu',
'default'=>false);
$this->default->cache['time'] = array(
'desc'=>'How long to cache our TSM queries',
'default'=>600);
/** Commands
* Define which high level commands are available.
*/
$this->default->commands['all'] = array(
'desc'=>'Define command availability',
'default'=> array(
'home' => true,
'login' => true,
'logout' => true,
'purge' => true,
'showcache' => true,
'register' => true
));
/** Debug Attributes
* Attributes that control debugging
*/
$this->default->debug['level'] = array(
'desc'=>'Debug level verbosity',
'default'=>0);
$this->default->debug['syslog'] = array(
'desc'=>'Whether to send debug messages to syslog',
'default'=>false);
$this->default->debug['file'] = array(
'desc'=>'Name of file to send debug output to',
'default'=>null);
$this->default->debug['addr'] = array(
'desc'=>'IP address of client to provide debugging info.',
'default'=>null);
$this->default->debug['append'] = array(
'desc'=>'Whether to append to the debug file, or create it fresh each time',
'default'=>true);
$this->default->debug['show_cache'] = array(
'desc'=>'Show the tool that shows debugging information.',
'default'=>false);
/** Session Attributes
* Session related attributes.
*/
$this->default->session['blowfish'] = array(
'desc'=>'Blowfish key to encrypt cookie details',
'default'=>null);
$this->default->session['memorylimit'] = array(
'desc'=>'Set the PHP memorylimit warning threshold.',
'default'=>24);
$this->default->session['timelimit'] = array(
'desc'=>'Set the PHP timelimit.',
'default'=>30);
/** Cookie Time
* If you used auth_type 'form' in the servers list, you can adjust how long the cookie will last
* (default is 0 seconds, which expires when you close the browser)
*/
$this->default->session['cookie_time'] = array(
'desc'=>'Time in seconds for the life of cookies',
'default'=>0);
/** Session Menu
*/
$this->default->menu['session'] = array(
'desc'=>'Menu items when logged in.',
'default'=>array(
'info'=>array('php'=>'info.php','icon'=>'info.png','text'=>'Server Info')
));
/** Available Commands
*/
}
/**
* Access the configuration, taking into account the defaults and the customisations
*/
private function getConfigArray($usecache=true) {
static $CACHE = array();
if ($usecache && count($CACHE))
return $CACHE;
foreach ($this->default as $key => $vals)
$CACHE[$key] = $vals;
foreach ($this->custom as $key => $vals)
foreach ($vals as $index => $val)
$CACHE[$key][$index]['value'] = $val;
return $CACHE;
}
/**
* Get a configuration value.
*/
public function getValue($key,$index,$fatal=true) {
$config = $this->getConfigArray();
if (! isset($config[$key]))
if ($fatal)
error(sprintf('A call was made in [%s] to getValue requesting [%s] that isnt predefined.',
basename($_SERVER['PHP_SELF']),$key),'error',null,true);
else
return null;
if (! isset($config[$key][$index]))
if ($fatal)
error(sprintf('Requesting an index [%s] in key [%s] that isnt predefined.',$index,$key),'error',null,true);
else
return null;
return isset($config[$key][$index]['value']) ? $config[$key][$index]['value'] : $config[$key][$index]['default'];
}
/**
* Return the untested config items
*/
public function untested() {
$result = array();
foreach ($this->default as $option => $details)
foreach ($details as $param => $values)
if (isset($values['untested']) && $values['untested'])
array_push($result,sprintf('%s.%s',$option,$param));
return $result;
}
/**
* Function to check and warn about any unusual defined variables.
*/
public function CheckCustom() {
if (isset($this->custom)) {
foreach ($this->custom as $masterkey => $masterdetails) {
if (isset($this->default->$masterkey)) {
if (! is_array($masterdetails))
error(sprintf('Error in configuration file, [%s] should be an ARRAY.',$masterdetails),'error',null,true);
foreach ($masterdetails as $key => $value) {
# Test that the key is correct.
if (! in_array($key,array_keys($this->default->$masterkey)))
error(sprintf('Error in configuration file, [%s] has not been defined as a configurable variable.',$key),'error',null,true);
# Test if its should be an array or not.
if (is_array($this->default->{$masterkey}[$key]['default']) && ! is_array($value))
error(sprintf('Error in configuration file, %s[\'%s\'] SHOULD be an array of values.',$masterkey,$key),'error',null,true);
if (! is_array($this->default->{$masterkey}[$key]['default']) && is_array($value))
error(sprintf('Error in configuration file, %s[\'%s\'] should NOT be an array of values.',$masterkey,$key),'error',null,true);
}
} else {
error(sprintf('Error in configuration file, [%s] has not been defined as a MASTER configurable variable.',$masterkey),'error',null,true);
}
}
}
}
/**
* Get a list of available commands.
*/
public function getCommandList() {
$config = $this->getConfigArray(false);
masort($config['command'],'summary');
if (isset($config['command']) && is_array($config['command']))
return $config['command'];
else
return array();
}
/**
* The parameter number is variable.
* For example : isCommandAvailable('search','simple_search')
*/
public function isCommandAvailable($index='all') {
$a = func_get_args();
if (! in_array($index,array('all','script')))
$index = 'all';
else
array_shift($a);
if (count($a) == 1 && is_array($a[0]))
$a = $a[0];
$i = 0;
# Command availability list
$cmd = $this->getValue('commands',$index);
# Search for the command
while ($i < count($a)) {
if (! is_array($cmd))
return $cmd;
if (! isset($cmd[$a[$i]]))
return false;
$cmd = $cmd[$a[$i]];
$i++;
}
# If this is a leaf command, return its availability
if (! is_array($cmd))
return $cmd;
# Else the command is available, if one of its sub-command is available
$a[] = '';
foreach ($cmd as $c => $v) {
$a[$i] = $c;
if ($this->isCommandAvailable($a))
return true;
}
return false;
}
public function configDefinition($key,$index,$config) {
if (! is_array($config) || ! array_key_exists('desc',$config) || ! array_key_exists('default',$config))
return;
if (isset($this->default->$key))
$definition = $this->default->$key;
$definition[$index] = $config;
$this->default->$key = $definition;
}
public function setServers($servers) {
$this->servers = $servers;
}
public function getServer($index=null) {
return $this->servers->Instance($index);
}
/**
* Return a list of our servers
* @param boolean $visible - Only return visible servers
*/
public function getServerList($visible=true) {
return $this->servers->getServerList($visible);
}
}
?>

501
lib/ds.php Normal file
View File

@ -0,0 +1,501 @@
<?php
// $Header: /cvsroot/phptsmadmin/phpTSMadmin/lib/ds.php,v 1.5 2009/04/19 04:15:21 wurley Exp $
/**
* Classes and functions for communication of Data Stores
*
* @author Deon George (c) 2009
* @package phpTSMadmin
*/
/**
* This abstract class provides the basic variables and methods.
*
* @package phpTSMadmin
* @subpackage DataStore
*/
abstract class DS {
# ID of this db.
protected $index;
# Configuration paramters.
protected $default;
protected $custom;
protected $type;
abstract function __construct($index);
/**
* This will make the connection to the datasource
*/
abstract protected function connect($method,$debug=false);
/**
* Login to the datastore
* method: default = anon, connect to ds using bind_id not auth_id.
* method: 'user', connect with auth_id
* method: '<freetext>', any custom extra connection to ds.
*/
abstract public function login($user=null,$pass=null,$method=null);
/**
* Query the datasource
*/
abstract public function query($query,$method,$index=null,$debug=false);
/**
* Return error details from previous operation
*/
abstract protected function getErrorMessage();
abstract protected function getErrorNum();
/**
* Functions that set and verify object configuration details
*/
public function setDefaults($defaults) {
foreach ($defaults as $key => $details)
foreach ($details as $setting => $value)
$this->default->{$key}[$setting] = $value;
}
public function isDefaultKey($key) {
return isset($this->default->$key);
}
public function isDefaultSetting($key,$setting) {
return array_key_exists($setting,$this->default->{$key});
}
/**
* Return a configuration value
*/
public function getValue($key,$setting,$fatal=true) {
if (isset($this->custom->{$key}[$setting]))
return $this->custom->{$key}[$setting];
elseif (isset($this->default->{$key}[$setting]) && array_key_exists('default',$this->default->{$key}[$setting]))
return $this->default->{$key}[$setting]['default'];
else {
if ($fatal)
debug_dump_backtrace("Error trying to get a non-existant value ($key,$setting)",1);
else
return null;
}
}
/**
* Set a configuration value
*/
public function setValue($key,$setting,$value) {
if (isset($this->custom->{$key}[$setting]))
system_message(array(
'title'=>_('Configuration setting already defined.'),
'body'=>sprintf('A call has been made to reset a configuration value (%s,%s,%s)',
$key,$setting,$value),
'type'=>'info'));
$this->custom->{$key}[$setting] = $value;
}
/**
* Return the untested config items
*/
public function untested() {
$result = array();
foreach ($this->default as $option => $details)
foreach ($details as $param => $values)
if (isset($values['untested']) && $values['untested'])
array_push($result,sprintf('%s.%s',$option,$param));
return $result;
}
/**
* Get the name of this datastore
*/
public function getName() {
return $this->getValue('server','name');
}
/**
* Functions that enable login and logout of the application
*/
/**
* Return the authentication type for this object
*/
public function getAuthType() {
switch ($this->getValue('login','auth_type')) {
case 'config' :
case 'session' :
return $this->getValue('login','auth_type');
default :
die(sprintf('Error: <b>%s</b> hasnt been configured for auth_type <b>%s</b>',__METHOD__,
$this->getValue('login','auth_type')));
}
}
/**
* Get the login name of the user logged into this datastore's connection method
*/
public function getLogin($method=null) {
$method = $this->getMethod($method);
switch ($this->getAuthType()) {
case 'config' :
return $this->getValue('login','bind_id');
case 'session' :
if (! isset($_SESSION['USER'][$this->index][$method]['name']))
return null;
return $_SESSION['USER'][$this->index][$method]['name'];
default :
die(sprintf('Error: %s hasnt been configured for auth_type %s',__METHOD__,$this->getAuthType()));
}
}
/**
* Set the login details of the user logged into this datastore's connection method
*/
protected function setLogin($user,$pass,$method=null) {
$method = $this->getMethod($method);
switch ($this->getAuthType()) {
case 'config' :
case 'session' :
$_SESSION['USER'][$this->index][$method]['name'] = $user;
$_SESSION['USER'][$this->index][$method]['pass'] = $pass;
return true;
default :
die(sprintf('Error: %s hasnt been configured for auth_type %s',__METHOD__,$this->getAuthType()));
}
}
/**
* Get the login password of the user logged into this datastore's connection method
*/
protected function getPassword($method=null) {
$method = $this->getMethod($method);
switch ($this->getAuthType()) {
case 'config' :
return $this->getValue('login','bind_pass');
case 'session' :
return (isset($_SESSION['USER'][$this->index][$method]['pass'])) ? $_SESSION['USER'][$this->index][$method]['pass'] : null;
default :
die(sprintf('Error: %s hasnt been configured for auth_type %s',__METHOD__,$this->getAuthType()));
}
}
/**
* Return if this datastore's connection method has been logged into
*/
public function isLoggedIn($method=null) {
$method = $this->getMethod($method);
return is_null($this->getLogin($method)) ? false : true;
}
/**
* Logout of this datastore's connection method
*/
public function logout($method) {
$method = $this->getMethod($method);
switch ($this->getAuthType()) {
case 'config' :
return true;
case 'session' :
if (isset($_SESSION['USER'][$this->index][$method]))
unset($_SESSION['USER'][$this->index][$method]);
return true;
default :
die(sprintf('Error: %s hasnt been configured for auth_type %s',__METHOD__,$this->getAuthType()));
}
}
/**
* Functions that return the condition of the datasource
*/
public function isVisible() {
return $this->getValue('server','visible');
}
public function isReadOnly() {
return $this->getValue('server','read_only');
}
public function getIndex() {
return $this->index;
}
/**
* Work out which connection method to use.
* If a method is passed, then it will be passed back. If no method is passed, then we'll
* check to see if the user is logged in. If they are, then 'user' is used, otherwise
* 'anon' is used.
*
* @param int Server ID
* @return string Connection Method
*/
protected function getMethod($method=null) {
# Immediately return if method is set.
if (! is_null($method))
return $method;
if ($this->isLoggedIn('user'))
return 'user';
else
return 'anon';
}
/**
* Get a attribute value from a query
*/
public function getAttrValue($query,$attr,$method=null,$debug=false) {
$result = $this->query($query,$method,$attr,$debug);
if ($debug)
debug_dump(array('query'=>$query,'result'=>$result));
if (count($result) > 1)
system_message(array(
'title'=>_('Invalid call to function.'),
'body'=>sprintf('%s should have return 0 or 1 value, but return %s (%s)<br />(%s)',
__METHOD__,count($result),serialize($result),serialize($query)),
'type'=>'info'));
else
foreach ($result as $key => $value)
return $value;
}
}
/**
* The list of database sources
*
* @package leenooksApp
* @subpackage DataStore
*/
class Datastore {
# Out DS index id
private $index;
# List of all the objects
private $objects = array();
# Default settings
private $default;
public function __construct() {
$this->default = new StdClass;
$this->default->server['id'] = array(
'desc'=>'Server ID',
'default'=>null);
$this->default->server['name'] = array(
'desc'=>'Server name',
'default'=>null);
# Connectivity Info
$this->default->server['host'] = array(
'desc'=>'Host Name',
'default'=>'127.0.0.1');
$this->default->server['port'] = array(
'desc'=>'Port Number',
'default'=>null);
# Read or write only access
$this->default->server['read_only'] = array(
'desc'=>'Server is in READ ONLY mode',
'default'=>false);
$this->default->server['visible'] = array(
'desc'=>'Whether this server is visible',
'default'=>true);
# Authentication Information
$this->default->login['auth_type'] = array(
'desc'=>'Authentication Type',
'default'=>'session');
/*
/* ID to login to this application, this assumes that there is
* application authentication on top of authentication required to
* access the data source **
$this->default->login['auth_id'] = array(
'desc'=>'User Login ID to login to this DS',
'default'=>null);
$this->default->login['auth_pass'] = array(
'desc'=>'User Login Password to login to this DS',
'default'=>null);
*/
$this->default->login['auth_text'] = array(
'desc'=>'Text to show at the login prompt',
'default'=>'User Name');
$this->default->login['bind_id'] = array(
'desc'=>'User Login ID to bind to this DS',
'default'=>null);
$this->default->login['bind_pass'] = array(
'desc'=>'User Login Password to bind to this DS',
'default'=>null);
$this->default->login['timeout'] = array(
'desc'=>'Session timout in seconds',
'default'=>session_cache_expire()-1);
# Location to custom pages
$this->default->custom['pages_prefix'] = array(
'desc'=>'Prefix name for custom pages',
'default'=>null);
}
/**
* Create a new database object
*/
public function newServer($type) {
if (class_exists($type)) {
$this->index = count($this->objects)+1;
$this->objects[$this->index] = new $type($this->index);
$this->objects[$this->index]->setDefaults($this->default);
return $this->index;
} else {
printf('ERROR: Class [%s] doesnt exist',$type);
die();
}
}
/**
* Set values for a database object.
*/
public function setValue($key,$setting,$value) {
if (defined('DEBUG_ENABLED') && (DEBUG_ENABLED))
debug_log('Entered with (%s,%s,%s)',3,__FILE__,__LINE__,__METHOD__,
$key,$setting,$value);
if (! $this->objects[$this->index]->isDefaultKey($key))
error("ERROR: Setting a key [$key] that isnt predefined.",'error',true);
if (! $this->objects[$this->index]->isDefaultSetting($key,$setting))
error("ERROR: Setting a index [$key,$setting] that isnt predefined.",'error',true);
# Test if its should be an array or not.
if (is_array($this->objects[$this->index]->getValue($key,$setting)) && ! is_array($value))
error("Error in configuration file, {$key}['$this->index'] SHOULD be an array of values.",'error',true);
if (! is_array($this->objects[$this->index]->getValue($key,$setting)) && is_array($value))
error("Error in configuration file, {$key}['$this->index'] should NOT be an array of values.",'error',true);
# Store the value in the object.
$this->objects[$this->index]->setValue($key,$setting,$value);
}
/**
* Get a list of all the configured servers.
*
* @param boolean Only show visible servers.
* @return array list of all configured servers.
*/
public function getServerList($isVisible=true) {
static $CACHE;
if (! isset($CACHE[$isVisible])) {
if (defined('DEBUG_ENABLED') && DEBUG_ENABLED)
debug_log('Entered with (%s)',3,__FILE__,__LINE__,__METHOD__,$isVisible);
$CACHE[$isVisible] = array();
# Debugging incase objects is not set.
if (! $this->objects) {
print "<PRE>";
debug_print_backtrace();
die();
}
foreach ($this->objects as $id => $server)
if (! $isVisible || ($isVisible && $server->getValue('server','visible')))
$CACHE[$isVisible][$id] = $server;
}
if (defined('DEBUG_ENABLED') && DEBUG_ENABLED)
debug_log('Entered with (%s), Returning (%s)',3,__FILE__,__LINE__,__METHOD__,
$isVisible,$CACHE);
return $CACHE[$isVisible];
}
/**
* Return an object Instance of a configured database.
*
* @param int Index
* @return object Datastore instance object.
*/
public function Instance($index=null) {
if (defined('DEBUG_ENABLED') && DEBUG_ENABLED)
debug_log('Entered with (%s)',3,__FILE__,__LINE__,__METHOD__,$index);
# If no index defined, then pick the lowest one.
if (is_null($index))
$index = min($this->GetServerList())->getIndex();
if (! isset($this->objects[$index]))
debug_dump_backtrace("Error: Datastore instance [$index] doesnt exist?",1);
if (defined('DEBUG_ENABLED') && DEBUG_ENABLED)
debug_log('Returning instance of database (%s)',3,__FILE__,__LINE__,__METHOD__,$index);
return $this->objects[$index];
}
/**
* Return an object Instance of a configured database.
*
* @param string Name of the instance to retrieve
* @return object Datastore instance object.
*/
public function InstanceName($name=null) {
if (DEBUG_ENABLED)
debug_log('Entered with (%s)',3,__FILE__,__LINE__,__METHOD__,$name);
foreach ($this->getServerList(false) as $index)
if ($this->objects[$index]->getName() == $name)
return $this->objects[$index];
# If we get here, then no object with the name exists.
return null;
}
/**
* Return an object Instance of a configured database.
*
* @param string ID of the instance to retrieve
* @return object Datastore instance object.
*/
public function InstanceId($id=null) {
if (DEBUG_ENABLED)
debug_log('Entered with (%s)',3,__FILE__,__LINE__,__METHOD__,$id);
foreach ($this->getServerList(false) as $index)
if ($this->objects[$index->getIndex()]->getValue('server','id') == $id)
return $this->objects[$index->getIndex()];
# If we get here, then no object with the name exists.
return null;
}
}
?>

712
lib/ds_tsm.php Normal file
View File

@ -0,0 +1,712 @@
<?php
// $Header: /cvsroot/phptsmadmin/phpTSMadmin/lib/ds_tsm.php,v 1.8 2009/04/19 04:03:05 wurley Exp $
/**
* @package phpTSMadmin
* @author Deon George (c) 2006
*/
class tsm extends DS {
public function __construct($index) {
$this->index = $index;
$this->type = 'tsm';
# Additional values that can go in our config.php
$this->custom = new StdClass;
$this->default = new StdClass;
# TSM Server Stanza Name
$this->default->server['stanza'] = array(
'desc'=>'TSM Server Stanza Name',
'default'=>null);
$this->default->system['dsmadmc'] = array(
'desc'=>'Path to dsmadmc command.',
'default'=>'/opt/tivoli/tsm/client/ba/bin/dsmadmc');
$this->default->system['errorlog'] = array(
'desc'=>'Set errorlog filename',
'default'=>'/tmp/pta-tsm-errorlog.log');
$this->default->system['tapeage'] = array(
'desc'=>'Age of tapes to alert for rotation',
'default'=>180);
# TSM Parameters
$this->default->tsmparm['msgFormat'] = array(
'desc'=>'Format of TSM message codes.',
'default'=>'[A-Z]{3}[0-9]{4}[I|E|W|S]');
$this->default->tsmparm['queryStartMsg'] = array(
'desc'=>'TSM code depicting START of queries results.',
'default'=>'ANS8000I');
$this->default->tsmparm['queryEndMsg'] = array(
'desc'=>'TSM code depicting END of queries results.',
'default'=>'ANS8002I');
$this->default->tsmparm['loginFail'] = array(
'desc'=>'Known TSM "failed login" message codes.',
'default'=>array(
'ANS8023E', //
'ANS1017E', // TCP/IP connection rejected.
'ANS1217E', // Server name not found in System Options File
'ANS1355E', // Sessions disabled.
'ANS8034E' // Your administrator ID is not recognized by this server.
));
$this->default->tsmparm['loginFailIgnore'] = array(
'desc'=>'Known TSM "ignore" message codes during login.',
'default'=>array(
'ANS0110E', // LogMsg: Unable to open error log file '%s' for output.
'ANS8002I' // Highest return code was %s.
));
$this->default->tsmparm['ignoremsg'] = array(
'desc'=>'Known TSM "ignore" message codes.',
'default'=>array(
'ANS8001I', // Return code %s.
'ANS0102W' // Unable to open the message repository %s. The American English repository will be used instead.
));
$this->default->tsmparm['nodatamsg'] = array(
'desc'=>'Known TSM "select returned no data" message codes.',
'default'=>array(
'ANR2034E' // SELECT: No match found using this criteria.
));
}
/**
* Required ABSTRACT functions
*/
/**
* Connect and Bind to the Database
*
* @param method This enables to have multiple different types of connects, ie: read only, readwrite, etc
* @return resource|null Connection resource if successful, null if not.
*/
protected function connect($method,$debug=false) {
$method = $this->getMethod($method);
if (! $this->isLoggedIn($method))
system_message(array('title'=>'Not Logged In',
'body'=>sprintf('You are not logged into server %s',$this->getValue('server','name')),
'type'=>'warn'),'index.php');
if (! file_exists($this->getValue('system','dsmadmc'))) {
system_message(array('title'=>'Cant find DSMADMC',
'body'=>sprintf('Unable to find the dsmadmc at <b>%s</b>',$this->getValue('system','dsmadmc')),
'type'=>'error'));
return false;
}
if ($this->getValue('system','errorlog'))
$errorlog = sprintf('-errorlogname=%s',$this->getValue('system','errorlog'));
if (is_null($this->getValue('server','stanza')) || ! trim($this->getValue('server','stanza')))
$TSMcmd = sprintf('%s -id=%s -password=%s -displ=list %s',
$this->getValue('system','dsmadmc'),$this->getLogin($method),$this->getPassword($method),
isset($errorlog) ? $errorlog : '');
else
$TSMcmd = sprintf('%s -se=%s -id=%s -password=%s -displ=list %s',
$this->getValue('system','dsmadmc'),
$this->getValue('server','stanza'),$this->getLogin($method),$this->getPassword($method),
isset($errorlog) ? $errorlog : '');
return $TSMcmd;
}
/**
* Login to the database with the application user/password
*
* @param method This enables to have multiple different types of connects, ie: read only, readwrite, etc
* @return boolean true|false for successful login.
*/
public function login($user=null,$pass=null,$method=null) {
# Set our user and password.
$this->setLogin($user,$pass,$method);
# Test that it works.
$result = $this->query('SELECT platform,version,release,level,sublevel FROM status',$method);
if (! $result)
$this->logout($method);
else
return true;
return false;
}
/**
* Perform a query to the Database
*
* @param string SQL query to perform
* @param string Index items according to this key
* @return array|null Results of query.
*/
public function query($query,$method,$index=null,$debug=false) {
$TSMcmd = sprintf('%s "%s"',$this->connect($method,$debug),$query);
$TSMcmdOutput = exec($TSMcmd,$OutputLines,$return);
if ($debug)
debug_dump(array('cmd'=>$TSMcmd,'TSMcmdOutput'=>$TSMcmdOutput,'return'=>$return));
# Parse the ouput for key:value pairs.
$outindex = 0;
$isQueryResult = 0;
$isKeyValue = 0;
$haveHelp = false;
$QueryResult = false;
$tsmCommands = array();
foreach ($OutputLines as $OutputLine ) {
$OutputLine = preg_replace('/\s+$/','',$OutputLine);
if ($debug)
debug_dump("($isQueryResult/$isKeyValue): WORKING line [$OutputLine]");
# See if we got a message number.
if (preg_match("/^(".$this->getValue('tsmparm','msgFormat').")\s+/",$OutputLine,$matches)) {
$msgnum = $matches[1];
if ($debug)
debug_dump("($isQueryResult/$isKeyValue): Got SYSTEM Msg [$OutputLine]");
# Filter through the output and check if we got our start message.
if (preg_match("/^".$this->getValue('tsmparm','queryStartMsg')."\s+/",$OutputLine)) {
if ($debug)
debug_dump("($isQueryResult/$isKeyValue): Got START Msg [$OutputLine]");
$isQueryResult = 1;
continue;
# Break out of loop when we get our end message.
} elseif (preg_match("/^".$this->getValue('tsmparm','queryEndMsg')."\s+/",$OutputLine)) {
if ($debug)
debug_dump("($isQueryResult/$isKeyValue): Got END Msg [$OutputLine]");
break;
}
if (in_array($msgnum,$this->getValue('tsmparm','nodatamsg')))
continue;
if (! in_array($msgnum,$this->getValue('tsmparm','ignoremsg')))
system_message(array('title'=>'TSM Message','body'=>$OutputLine));
}
# If we the line is a queryResult line
if ($isQueryResult) {
# See if we got a key:value pair, otherwise go to next line.
if (preg_match('/:/',$OutputLine) && ! (preg_match('/^help/',$query))) {
$OutputLine = preg_replace('/\s*:\s+/',':',$OutputLine);
list($key,$value) = explode(':',$OutputLine,2);
$isKeyValue = 1;
# Not key:value, so check if we need to increase the index.
} else {
# Is this a show slots command, so there is more info
if (preg_match('/^show slots/',$query)) {
if (preg_match('/^Slot /',$OutputLine)) {
foreach ((preg_split('/,\s*/',$OutputLine,-1)) as $slotkey => $val) {
if (preg_match('/^element number\s+/',$val)) {
$key = preg_replace('/^element number\s+/','',$val);
} elseif (preg_match('/^Slot\s+/',$val)) {
$slots['slot'] = preg_replace('/^Slot\s+/','',$val);
} elseif (preg_match('/^status\s+/',$val)) {
$slots['status'] = preg_replace('/^status\s+/','',$val);
} elseif (preg_match('/^barcode value </',$val)) {
$slots['barcodelabel'] = preg_replace('/^barcode value <(.*)>/',"$1",$val);
} elseif (preg_match('/^barcode\s+/',$val)) {
$slots['barcode'] = preg_replace('/^barcode /','',$val);
}
}
$QueryResult[$outindex]['SlotUsage'][$key] = $slots;
} elseif (preg_match('/busy.$/',$OutputLine)) {
system_message(array('title'=>'Library is Busy',
'body'=>sprintf('The library appears busy at the moment.<br />%s',$OutputLine),
'type'=>'info'),
sprintf('index.php',get_request('cmd','REQUEST') ? sprintf('cmd=%s',get_request('cmd','REQUEST')) : ''));
}
# Is this a help command, so there is more info
} elseif (preg_match('/^help$/',$query)) {
if (preg_match('/^\s*([0-9]+) - Commands /',$OutputLine)) {
$helpnum = preg_replace('/^\s*([0-9]+) - Commands .*/','$1',$OutputLine);
$tsmCommands = array_unique(array_merge($tsmCommands,$this->query("help $helpnum",null)));
}
} elseif (preg_match('/^help\s+[0-9]+/',$query)) {
if (! $OutputLine)
continue;
if (! $haveHelp && preg_match('/^\s*Command Name/',$OutputLine)) {
$haveHelp = true;
$helpCommands = array();
continue;
}
if ($haveHelp) {
# Filter out the beginning spaces.
$OutputLine = preg_replace('/^\s*/','',$OutputLine);
# Filter out the "(See Note)" messages.
$OutputLine = preg_replace('/\s\(.*\)/','',$OutputLine);
# Join the two columns together
$OutputLine = preg_replace('/\ \s+/','|',$OutputLine);
# We should now just have commands and they should be in uppercase.
if (preg_match('/[a-z0-9]/',$OutputLine))
continue;
#debug_dump("Im finally here with [$OutputLine].");
foreach (explode('|',$OutputLine) as $helpCMD)
array_push($helpCommands,$helpCMD);
}
} elseif (preg_match('/^help\s+[A-Z]+/',$query)) {
# Sometimes QueryResult gets data because of colons - we need to capture that.
if (isset($QueryResult) && is_array($QueryResult)) {
foreach ($QueryResult as $lineDetail)
foreach ($lineDetail as $key => $ldindex)
$helpText[] = $key.$ldindex;
$QueryResult = array();
}
$helpText[] = $OutputLine;
//debug_dump(array("Im finally here with [$OutputLine]."=>$QueryResult));
# If this is a blank line
} elseif (!$OutputLine) {
# Only increment index if the previous iteration was a key/value pair.
# Reset isKeyValue so we dont increase index for 2 non key:value lines in a row.
if ($isKeyValue) {
if (!preg_match('/^show/',$query))
$outindex++;
$isKeyValue = 0;
}
} // if
continue;
} // if
$key = preg_replace('/^\s+/','',$key);
$value = preg_replace('/^\s+/','',$value);
$QueryResult[$outindex][$key] = $value;
} // if
} // foreach
if (is_array($tsmCommands) && preg_match('/^help$/',$query)) {
asort($tsmCommands);
$QueryResult = $tsmCommands;
}
if (isset($helpCommands) && preg_match('/^help\s+[0-9]+/',$query))
$QueryResult = $helpCommands;
if (isset($helpText) && preg_match('/^help\s+[A-Z]+/',$query))
$QueryResult = $helpText;
if ($debug)
debug_dump($QueryResult,0);
if (! $isQueryResult && $debug)
Error(sprintf('The query <BR>%s<BR>didnt return anything [%s]',preg_replace('/-password=(.*)\ -/','-password=x -',$TSMcmd),serialize($OutputLines)));
if ($index && is_array($QueryResult)) {
foreach ($QueryResult as $result => $val) {
if (isset($val[$index]))
$IndexQueryResult[$val[$index]] = $QueryResult[$result];
}
return (isset($IndexQueryResult) ? $IndexQueryResult : false);
} elseif (is_array($QueryResult)) {
return $QueryResult;
}
return array();
}
/**
* Get the last error string
*/
protected function getErrorMessage() {
return null;
}
/**
* Get the last error number
*/
protected function getErrorNum() {
return null;
}
/**
* Return if anonymous bind is allowed in the configuration
*/
public function isAnonBindAllowed() {
return false;
}
/**
* Query the database for particular attributes values.
*/
public function queryAttr($table,$attrs,$key,$where=null,$orderby=null) {
return array();
}
/**
* Register user to the application
*/
public function register($user,$pass,$other=array()) {
return null;
}
/**
* Query TSM and get Database information
*/
function QueryDBDetail() {
$query = $this->query('select * from DB',null);
$this->CACHE['db'] = $query[0];
$this->CACHE['db']['dbvols'] = $this->query('select * from DBVOLUMES',null);
$this->CACHE['cache']['db'] = time();
$this->CACHE['cache']['log'] = time();
$query = $this->query('select * from LOG',null);
$this->CACHE['log'] = $query[0];
$this->CACHE['log']['logvols'] = $this->query('select * from LOGVOLUMES',null);
$_SESSION['tsm'][$this->index] = $this->CACHE;
}
/**
* Return the DB information.
* @param string attribute
* @return string value for attribute
*/
function GetDBDetail($attribute) {
if (! isset($this->CACHE['db'][$attribute]))
$this->QueryDBDetail();
if (! isset($this->CACHE['db'][$attribute]))
Error(sprintf(_('ERROR: A request to get DB attribute "%" didnt return a value'),$attribute));
return $this->CACHE['db'][$attribute];
}
/**
* Return the LOG information.
* @param string attribute
* @return string value for attribute
*/
function GetLogDetail($attribute) {
if (! isset($this->CACHE['log'][$attribute]))
$this->QueryDBDetail();
if (! isset($this->CACHE['log'][$attribute]))
Error(sprintf(_('ERROR: A request to get LOG attribute "%" didnt return a value'),$attribute));
return $this->CACHE['log'][$attribute];
}
/**
* Return the VOLUMES information
* @return array
*/
function GetVolumes() {
if (isset($this->CACHE['volumes']))
return $this->CACHE['volumes'];
$this->CACHE['volumes'] = $this->query('select * from VOLUMES',null,'VOLUME_NAME');
$this->CACHE['cache']['volumes'] = time();
$_SESSION['tsm'][$this->index] = $this->CACHE;
return $this->CACHE['volumes'];
}
/**
* Return the LIBVOLUMES information
* @return array
*/
function GetLibVolumes() {
if (isset($this->CACHE['libvols']))
return $this->CACHE['libvols'];
$this->CACHE['libvols'] = $this->query('select * from LIBVOLUMES',null,'HOME_ELEMENT');
$this->CACHE['cache']['libvols'] = time();
$_SESSION['tsm'][$this->index] = $this->CACHE;
return $this->CACHE['libvols'];
}
/**
* Return the DB Backup Volumes
* @return array
*/
function GetDBBackupInfo() {
if (isset($this->CACHE['dbbackup']))
return $this->CACHE['dbbackup'];
$this->CACHE['dbbackup']['vols'] = $this->query("select * from VOLHISTORY where TYPE in ('BACKUPFULL','BACKUPINCR','DBSNAPSHOT') order by BACKUP_SERIES,BACKUP_OPERATION,VOLUME_SEQ",
null,'VOLUME_NAME');
# Now check that a backup series is valid - since it should be in order.
$lastSeries = -1;
$backupfirst = '';
$backuplast = '';
$backupcount = 0;
if (is_array($this->CACHE['dbbackup']['vols'])) {
foreach ($this->CACHE['dbbackup']['vols'] as $volume => $voldetails) {
if ($lastSeries != $voldetails['BACKUP_SERIES']) {
$lastSeries = $voldetails['BACKUP_SERIES'];
$lastOperation = -1;
$lastSeq = 0;
if (! $backupfirst | $voldetails['DATE_TIME'] < $backupfirst)
$backupfirst = $voldetails['DATE_TIME'];
if (! $backuplast | $voldetails['DATE_TIME'] > $backuplast)
$backuplast = $voldetails['DATE_TIME'];
$backupcount++;
}
# No point trying this series if it is invalid.
if (isset($status[$voldetails['BACKUP_SERIES']]['status']) &&
($status[$voldetails['BACKUP_SERIES']]['status'] == 'InValid'))
continue;
$this->CACHE['dbbackup']['vols'][$volume]['STATUS'] = 'Valid';
if (($voldetails['BACKUP_OPERATION'] == $lastOperation) || ($voldetails['BACKUP_OPERATION']-1 == $lastOperation)) {
$status[$voldetails['BACKUP_SERIES']]['status'] = 'Valid';
$lastOperation = $voldetails['BACKUP_OPERATION'];
} else {
$status[$voldetails['BACKUP_SERIES']]['status'] = 'InValid';
$status[$voldetails['BACKUP_SERIES']]['statusreason'] = sprintf(_('Missing SERIES volumes, expected [%s], found [%s].'),
$lastOperation+1,$voldetails['BACKUP_OPERATION']);
continue;
}
if (($voldetails['VOLUME_SEQ'] == $lastSeq) || $voldetails['VOLUME_SEQ']-1 == $lastSeq) {
$status[$voldetails['BACKUP_SERIES']]['status'] = 'Valid';
$lastSeq = $voldetails['VOLUME_SEQ'];
} else {
$status[$voldetails['BACKUP_SERIES']]['status'] = 'InValid';
$status[$voldetails['BACKUP_SERIES']]['statusreason'] = sprintf(_('Missing SERIES volumes, expected [%s], found [%s].'),$lastSeq+1,$voldetails['VOLUME_SEQ']);
}
$lastSeq = $voldetails['VOLUME_SEQ'];
}
# Now we know which series are invalid, mark all the volumes.
foreach ($this->CACHE['dbbackup']['vols'] as $volume => $voldetails) {
$this->CACHE['dbbackup']['vols'][$volume]['STATUS'] = $status[$voldetails['BACKUP_SERIES']]['status'];
if (isset($status[$voldetails['BACKUP_SERIES']]['statusreason']))
$this->CACHE['dbbackup']['vols'][$volume]['STATUSREASON'] = $status[$voldetails['BACKUP_SERIES']]['statusreason'];
}
}
# Grab backup information
$history = $this->query('select DATE_TIME,MSGNO,MESSAGE from ACTLOG where MSGNO in (4550,4551) order by DATE_TIME',null);
if (! isset($history[0]['ANR2034E SELECT']))
foreach ($history as $index => $historydetail) {
$this->CACHE['dbbackup']['history'][$index]['date'] = $historydetail['DATE_TIME'];
switch ($historydetail['MSGNO']) {
case 4550:
if (preg_match('/([0-9]+) pages copied./',$historydetail['MESSAGE'],$matchall)) {
$this->CACHE['dbbackup']['history'][$index]['size'] = $matchall[1];
$this->CACHE['dbbackup']['history'][$index]['type'] = 'FULL';
}
break;
case 4551:
if (preg_match('/([0-9]+) pages copied./',$historydetail['MESSAGE'],$matchall)) {
$this->CACHE['dbbackup']['history'][$index]['size'] = $matchall[1];
$this->CACHE['dbbackup']['history'][$index]['type'] = 'INCR';
}
break;
default:
printf('Message %s not catered for [%s]...',$historydetail['MSGNO'],$historydetail['MESSAGE']);
die();
}
}
# Get DBBackup Trigger information.
$select = $this->query('select * from DBBACKUPTRIGGER',null);
$result = array_shift($select);
if (isset($result['ANR2034E SELECT']))
$this->CACHE['dbbackup']['trigger'] = false;
else
$this->CACHE['dbbackup']['trigger'] = $result;
$this->CACHE['dbbackup']['first'] = $backupfirst;
$this->CACHE['dbbackup']['last'] = $backuplast;
$this->CACHE['dbbackup']['count'] = $backupcount;
$this->CACHE['cache']['dbbackup'] = time();
$_SESSION['tsm'][$this->index] = $this->CACHE;
return $this->CACHE['dbbackup'];
}
function GetDBBackupDetail($detail) {
if (isset($this->CACHE['dbbackup'][$detail]))
return $this->CACHE['dbbackup'][$detail];
$this->GetDBBackupInfo();
if (isset($this->CACHE['dbbackup'][$detail]))
return $this->CACHE['dbbackup'][$detail];
else
return null;
}
/**
* Return the Status Information
* @return array
*/
function GetStatus() {
if (isset($this->CACHE['status']))
return $this->CACHE['status'];
$select = $this->query('select * from STATUS',null);
$this->CACHE['status'] = array_shift($select);
$this->CACHE['cache']['status'] = time();
$_SESSION['tsm'][$this->index] = $this->CACHE;
return $this->CACHE['status'];
}
function GetStatusDetail($detail) {
if (isset($this->CACHE['status'][$detail]))
return $this->CACHE['status'][$detail];
$this->GetStatus();
if (isset($this->CACHE['status'][$detail]))
return $this->CACHE['status'][$detail];
else
return null;
}
/**
* Get TSM event information
* @param string Start date for report
* @param string End date for report
* @param string order by key.
* @return array Query result
*/
function GetEvents($reportStart='',$reportEnd='',$orderby='SCHEDULED_START') {
if (isset($this->CACHE['events']) && $reportStart == $this->CACHE['events']['start'] &&
$reportEnd == $this->CACHE['events']['end'] && $orderby == $this->CACHE['events']['orderby'])
return $this->CACHE['events'];
$TSMQuery = 'select * from EVENTS where DOMAIN_NAME is not null';
if (($reportStart) && ($reportEnd))
$TSMQuery .= sprintf(" and (SCHEDULED_START between '%s' and '%s')",$reportStart,$reportEnd);
else if ($reportStart)
$TSMQuery .= sprintf(" and SCHEDULED_START \> '%s'",$reportStart);
else if ($reportEnd)
$TSMQuery .= sprintf(" and SCHEDULED_START <= '%s'",$reportEnd);
$TSMQuery .= sprintf(' order by %s',$orderby);
$result = $this->query($TSMQuery,null);
if (isset($result[0]['ANR2034E SELECT'])) {
$this->CACHE['events'] = false;
} else {
$this->CACHE['events']['detail'] = $result;
$this->CACHE['events']['start'] = $reportStart;
$this->CACHE['events']['end'] = $reportEnd;
$this->CACHE['events']['orderby'] = $orderby;
}
$this->CACHE['cache']['events'] = time();
$_SESSION['tsm'][$this->index] = $this->CACHE;
return $this->CACHE['events'];
}
/**
* Get TSM Activity Log Client backup information.
* @param string Start date for report
* @param string End date for report
* @return array Query result
*/
function GetActlogBackupSummary($reportStart='',$reportEnd='') {
if (isset($this->CACHE['actlogbackup']) && $reportStart == $this->CACHE['actlogbackup']['start'] &&
$reportEnd == $this->CACHE['actlogbackup']['end'])
return $this->CACHE['actlogbackup'];
$tsmMSG['4952'] = 'Inspected';
$tsmMSG['4954'] = 'Backup';
$tsmMSG['4958'] = 'Update';
$tsmMSG['4957'] = 'Delete';
$tsmMSG['4959'] = 'Failed';
$tsmMSG['4960'] = 'Rebound';
$tsmMSG['4961'] = 'Transfer';
$tsmMSG['4964'] = 'ProcTime';
$tsmMSG['4967'] = 'AggRate';
$tsmMSG['4968'] = 'Compress';
$tsmMSG['4970'] = 'Expire';
$TSMQuery = sprintf('select MSGNO,NODENAME,SESSID,MESSAGE,SCHEDNAME,DOMAINNAME from ACTLOG where MSGNO in (%s)',
implode(',',array_keys($tsmMSG)));
if (($reportStart) && ($reportEnd))
$TSMQuery .= sprintf(" and (DATE_TIME between '%s' and '%s')",$reportStart,$reportEnd);
else if ($reportStart)
$TSMQuery .= sprintf(" and DATE_TIME \> '%s'",$reportStart);
else if ($reportEnd)
$TSMQuery .= sprintf(" and DATE_TIME <= '%s'",$reportEnd);
$TSMQuery .= ' order by sessid';
foreach ($this->query($TSMQuery,null) as $tsmBackup => $tsmSession) {
# TSM on AIX adds a "SESSION" at the end of each line - maybe others do as well.
if (isset($tsmSession['MESSAGE']))
$tsmSession['MESSAGE'] = preg_replace('/\(SESSION:.*\)/','',$tsmSession['MESSAGE']);
$tsmBackupSummary['detail'][$tsmSession['NODENAME']][$tsmSession['SESSID']][$tsmMSG[$tsmSession['MSGNO']]] = preg_replace('/^.*:\s*/U','',$tsmSession['MESSAGE']);
}
$tsmBackupSummary['start'] = $reportStart;
$tsmBackupSummary['end'] = $reportEnd;
$this->CACHE['actlogbackup'] = $tsmBackupSummary;
$this->CACHE['cache']['actlogbackup'] = time();
$_SESSION['tsm'][$this->index] = $this->CACHE;
return $this->CACHE['actlogbackup'];
}
function GetVolLocation($vol) {
$volumes = $this->GetVolumes();
if ($this->GetLibVolumes())
foreach ($this->GetLibVolumes() as $slot => $details) {
if ($details['VOLUME_NAME'] == $vol)
return sprintf('**%s %s**',_('LIBRARY'),$details['LIBRARY_NAME']);
}
if (isset($volumes[$vol]))
return $volumes[$vol]['LOCATION'];
# If we get here, we dont know where the volume is.
return null;
}
}
?>

330
lib/functions.custom.php Normal file
View File

@ -0,0 +1,330 @@
<?php
# $Header: /cvsroot/phptsmadmin/phpTSMadmin/lib/functions.custom.php,v 1.2 2009/04/19 04:03:05 wurley Exp $
/**
* Classes and functions for TSM server configuration and capability
*
* @author The phpTSMadmin development team
* @package phpTSMadmin
*/
/**
* Prune the .decimals from the TSM dates.
* @param string Date
* @param string Prune key
* @return string Date in required format
*/
function tsmDate($string,$prune='') {
switch ($prune) {
case 'notime' :
$regexp = '/ [0-9]+:.*$/';
break;
case 'nosec' :
$regexp = '/:[0-9]+\.[0-9]*$/';
break;
case 'nomsec' :
$regexp = '/^([0-9]+-[0-9]+-[0-9]+ [0-9]+:[0-9]+:[0-9]+)\..*/';
break;
case 'daytime' :
$regexp = '/^[0-9]+-[0-9]+-([0-9]+ [0-9]+:[0-9]+).*/';
break;
case 'monthdaytime' :
$regexp = '/^[0-9]+-([0-9]+-[0-9]+ [0-9]+:[0-9]+).*/';
break;
default :
$regexp = '/\.[0-9]*$/';
}
return (preg_replace($regexp,'$1',$string));
}
/**
* Translate backup types into meaningful strings.
* @param string TSM backup string
* @return string
*/
function tsmBackupType($string) {
switch ($string) {
case 'BACKUPINCR' : return 'INCR';
break;
case 'BACKUPFULL' : return 'FULL';
break;
case 'DBSNAPSHOT' : return 'SNAPSHOT';
break;
default : return $string;
break;
}
}
function isPrimaryPool($pool) {
global $app;
objectCache('stgps');
return $_SESSION['cache'][$app['server']->getIndex()]['stgps']->isPrimaryPool($pool);
}
function isCopyPool($pool) {
global $app;
objectCache('stgps');
return $_SESSION['cache'][$app['server']->getIndex()]['stgps']->isCopyPool($pool);
}
function getReclaim($pool) {
global $app;
objectCache('stgps');
return $_SESSION['cache'][$app['server']->getIndex()]['stgps']->getReclaim($pool);
}
function getReUse($pool) {
global $app;
objectCache('stgps');
return $_SESSION['cache'][$app['server']->getIndex()]['stgps']->getReUse($pool);
}
function getVolume($vol) {
global $app;
objectCache('volumes');
return $_SESSION['cache'][$app['server']->getIndex()]['volumes']->getVolume($vol);
}
function isLibraryDevClass($devclass) {
global $app;
objectCache('devclasses');
return $_SESSION['cache'][$app['server']->getIndex()]['devclasses']->isLibraryDevClass($devclass);
}
function LibraryDevClass($devclass) {
global $app;
objectCache('devclasses');
return $_SESSION['cache'][$app['server']->getIndex()]['devclasses']->LibraryDevClass($devclass);
}
/**
* Return the name that a cookie will be stored by the browser.
* @param int Server ID.
* @param string Name of Cookie.
* @return string Fully qualified cookie name.
*/
function cookie_name($index,$name) {
global $app;
return $app['server']->getValue('cookie','prefix').$index.$name;
}
/**
* Returns the value of cookie
* @param int Server ID
* @param string Name
* @return string|false Value of cookie (null if not set/no value)
*/
function get_cookie($index,$name) {
global $_COOKIE;
$cookie = cookie_name($index,$name);
if (isset($_COOKIE[$cookie]))
return $_COOKIE[$cookie];
else
return false;
}
/**
* Store a cookie in the user browser.
* @param int Server ID
* @param string Name of Cookie
* @param string Value for Cookie
* @param int Time for cookie to live in seconds
* @param string dir Cookie Path
* @result boolean
*/
function store_cookie($index,$name,$val,$expire=null,$dir=null) {
global $app;
$cookie_name = cookie_name($index,$name);
$cookie_time = $app['server']->getValue('cookie','time');
if ($expire == null)
$expire = ($cookie_time == 0 ? null : time() + $cookie_time);
if ($dir == null)
$dir = dirname($app['server']->getValue('server','path') ? $app['server']->getValue('server','path') : '/');
if (setcookie($cookie_name,$val,$expire,$dir))
return true;
else
return false;
}
/**
* Unset all cookies on logout.
* @param int Server ID
* @result boolean True if successful, false if not
* @todo: No routine to call this.
*/
function unset_cookie($index) {
global $app;
global $_COOKIE;
$expire = time()-3600;
foreach ($_COOKIE as $cookie => $cookie_value) {
$cookie = preg_replace("/^".$app['server']->getValue('server','path').$index.'/','',$cookie);
if ($cookie == 'PHPSESSID') continue;
$result = store_cookie($index,$cookie,'',$expire) ;
if (! $result) return false;
}
return true;
}
/**
* Initialise JPgraph
* @param boolean Must initialise or fail with an error if unable to do so
*/
function initJPGraph($need=false) {
$jpgraph = $_SESSION[APPCONFIG]->getValue('lib','jpgraph');
if (! $jpgraph)
if ($need)
die(_('Your JPGRAPH setting in config.php is pointing to a directory that does not exist. Please fix your config.php'));
else
return false;
if ((! file_exists($jpgraph.'/src/jpgraph.php')) || (! file_exists($jpgraph.'/src/jpgraph_gantt.php')))
if ($need)
die(sprintf(_('PTA was not able to find the JPGRAPH utility in the "%s" directory. Either your config.php is pointing to the wrong directory, or you havent installed JPGRAPH'),$jpgraph));
else
return false;
if (! function_exists('imagetypes') && ! function_exists('imagecreatefromstring'))
if ($need)
die(_('It seems that GD support is not available. Please add GD support to PTA.'));
else
return false;
if (! is_dir($_SESSION[APPCONFIG]->getValue('image','path')) || ! is_writable($_SESSION[APPCONFIG]->getValue('image','path')))
die(sprintf(_('The temporary path for JPGRAPH either doesnt exist or is not writable - you have it configured for %s.'),$_SESSION[APPCONFIG]->getValue('image','path')));
# When we get here, we have all the pre-reqs.
error_reporting(0);
require_once $jpgraph.'/src/jpgraph.php';
require_once $jpgraph.'/src/jpgraph_gantt.php';
require_once $jpgraph.'/src/jpgraph_line.php';
require_once $jpgraph.'/src/jpgraph_bar.php';
require_once $jpgraph.'/src/jpgraph_pie.php';
require_once $jpgraph.'/src/jpgraph_date.php';
error_reporting(E_ALL);
return true;
}
/**
* Put some HTML classes around strings containing values.
* @param string String to parse
* @param string Class to substitute
* @return string String with <span class=$class> around %s
*/
function classValue($string,$class) {
return preg_replace('/(\%[0-9.]*[sf])/',"<span class=\"$class\">$1</span>$2",$string);
}
function objectCache($object,$force=false) {
global $app;
$index = $app['server']->getIndex();
if (DEBUG_ENABLED)
debug_log('objectCache(): Entered with (%s,%s)',1,$object,isset($_SESSION['cache'][$index][$object]));
if (isset($_SESSION['cache'][$index][$object])) {
if ($_SESSION['cache'][$index][$object]->expired() || $force) {
if (DEBUG_ENABLED)
debug_log('objectCache(): Object expired (%s,%s)',1,$_SESSION['cache'][$index][$object]->cache,time());
$_SESSION['cache'][$index][$object]->load();
$_SESSION['cache'][$index][$object]->cache = time();
}
} else {
switch($object) {
case 'devclasses' :
$_SESSION['cache'][$index][$object] = new deviceClasses($index);
break;
case 'drives' :
$_SESSION['cache'][$index][$object] = new drives($index);
break;
case 'help' :
$_SESSION['cache'][$index][$object] = new help($index);
break;
case 'libraries' :
$_SESSION['cache'][$index][$object] = new libraries($index);
break;
case 'mgmtclasses' :
$_SESSION['cache'][$index][$object] = new mgmtClasses($index);
break;
case 'nodes' :
$_SESSION['cache'][$index][$object] = new nodes($index);
break;
case 'occupancy' :
$_SESSION['cache'][$index][$object] = new occupancy($index);
break;
case 'stgps' :
$_SESSION['cache'][$index][$object] = new storagePools($index);
break;
case 'summaryinfo' :
$_SESSION['cache'][$index][$object] = new summaryInfo($index);
break;
case 'volumes' :
$_SESSION['cache'][$index][$object] = new volumes($index);
break;
default:
error(sprintf('Unknown object %s',$object));
}
$_SESSION['cache'][$index][$object]->cache = time();
}
return $_SESSION['cache'][$index][$object];
}
function render_page($title,$body) {
$www = new page();
if (is_array($title)) {
foreach ($title as $key => $title) {
$block = new block();
$block->SetTitle($title);
$block->SetBody($body[$key]);
$www->block_add('body',$block);
}
} else {
$block = new block();
$block->SetTitle($title);
$block->SetBody($body);
$www->block_add('body',$block);
}
$www->body();
}
?>

1018
lib/functions.php Normal file

File diff suppressed because it is too large Load Diff

330
lib/functions.tsm.php Normal file
View File

@ -0,0 +1,330 @@
<?php
# $Header: /cvsroot/phptsmadmin/phpTSMadmin/lib/functions.tsm.php,v 1.39 2009/04/19 04:03:05 wurley Exp $
/**
* Classes and functions for TSM server configuration and capability
*
* @author The phpTSMadmin development team
* @package phpTSMadmin
*/
/**
* Prune the .decimals from the TSM dates.
* @param string Date
* @param string Prune key
* @return string Date in required format
*/
function tsmDate($string,$prune='') {
switch ($prune) {
case 'notime' :
$regexp = '/ [0-9]+:.*$/';
break;
case 'nosec' :
$regexp = '/:[0-9]+\.[0-9]*$/';
break;
case 'nomsec' :
$regexp = '/^([0-9]+-[0-9]+-[0-9]+ [0-9]+:[0-9]+:[0-9]+)\..*/';
break;
case 'daytime' :
$regexp = '/^[0-9]+-[0-9]+-([0-9]+ [0-9]+:[0-9]+).*/';
break;
case 'monthdaytime' :
$regexp = '/^[0-9]+-([0-9]+-[0-9]+ [0-9]+:[0-9]+).*/';
break;
default :
$regexp = '/\.[0-9]*$/';
}
return (preg_replace($regexp,'$1',$string));
}
/**
* Translate backup types into meaningful strings.
* @param string TSM backup string
* @return string
*/
function tsmBackupType($string) {
switch ($string) {
case 'BACKUPINCR' : return 'INCR';
break;
case 'BACKUPFULL' : return 'FULL';
break;
case 'DBSNAPSHOT' : return 'SNAPSHOT';
break;
default : return $string;
break;
}
}
function isPrimaryPool($pool) {
global $app;
objectCache('stgps');
return $_SESSION['cache'][$app['server']->getIndex()]['stgps']->isPrimaryPool($pool);
}
function isCopyPool($pool) {
global $app;
objectCache('stgps');
return $_SESSION['cache'][$app['server']->getIndex()]['stgps']->isCopyPool($pool);
}
function getReclaim($pool) {
global $app;
objectCache('stgps');
return $_SESSION['cache'][$app['server']->getIndex()]['stgps']->getReclaim($pool);
}
function getReUse($pool) {
global $app;
objectCache('stgps');
return $_SESSION['cache'][$app['server']->getIndex()]['stgps']->getReUse($pool);
}
function getVolume($vol) {
global $app;
objectCache('volumes');
return $_SESSION['cache'][$app['server']->getIndex()]['volumes']->getVolume($vol);
}
function isLibraryDevClass($devclass) {
global $app;
objectCache('devclasses');
return $_SESSION['cache'][$app['server']->getIndex()]['devclasses']->isLibraryDevClass($devclass);
}
function LibraryDevClass($devclass) {
global $app;
objectCache('devclasses');
return $_SESSION['cache'][$app['server']->getIndex()]['devclasses']->LibraryDevClass($devclass);
}
/**
* Return the name that a cookie will be stored by the browser.
* @param int Server ID.
* @param string Name of Cookie.
* @return string Fully qualified cookie name.
*/
function cookie_name($index,$name) {
global $app;
return $app['server']->getValue('cookie','prefix').$index.$name;
}
/**
* Returns the value of cookie
* @param int Server ID
* @param string Name
* @return string|false Value of cookie (null if not set/no value)
*/
function get_cookie($index,$name) {
global $_COOKIE;
$cookie = cookie_name($index,$name);
if (isset($_COOKIE[$cookie]))
return $_COOKIE[$cookie];
else
return false;
}
/**
* Store a cookie in the user browser.
* @param int Server ID
* @param string Name of Cookie
* @param string Value for Cookie
* @param int Time for cookie to live in seconds
* @param string dir Cookie Path
* @result boolean
*/
function store_cookie($index,$name,$val,$expire=null,$dir=null) {
global $app;
$cookie_name = cookie_name($index,$name);
$cookie_time = $app['server']->getValue('cookie','time');
if ($expire == null)
$expire = ($cookie_time == 0 ? null : time() + $cookie_time);
if ($dir == null)
$dir = dirname($app['server']->getValue('server','path') ? $app['server']->getValue('server','path') : '/');
if (setcookie($cookie_name,$val,$expire,$dir))
return true;
else
return false;
}
/**
* Unset all cookies on logout.
* @param int Server ID
* @result boolean True if successful, false if not
* @todo: No routine to call this.
*/
function unset_cookie($index) {
global $app;
global $_COOKIE;
$expire = time()-3600;
foreach ($_COOKIE as $cookie => $cookie_value) {
$cookie = preg_replace("/^".$app['server']->getValue('server','path').$index.'/','',$cookie);
if ($cookie == 'PHPSESSID') continue;
$result = store_cookie($index,$cookie,'',$expire) ;
if (! $result) return false;
}
return true;
}
/**
* Initialise JPgraph
* @param boolean Must initialise or fail with an error if unable to do so
*/
function initJPGraph($need=false) {
$jpgraph = $_SESSION[APPCONFIG]->getValue('lib','jpgraph');
if (! $jpgraph)
if ($need)
die(_('Your JPGRAPH setting in config.php is pointing to a directory that does not exist. Please fix your config.php'));
else
return false;
if ((! file_exists($jpgraph.'/src/jpgraph.php')) || (! file_exists($jpgraph.'/src/jpgraph_gantt.php')))
if ($need)
die(sprintf(_('PTA was not able to find the JPGRAPH utility in the "%s" directory. Either your config.php is pointing to the wrong directory, or you havent installed JPGRAPH'),$jpgraph));
else
return false;
if (! function_exists('imagetypes') && ! function_exists('imagecreatefromstring'))
if ($need)
die(_('It seems that GD support is not available. Please add GD support to PTA.'));
else
return false;
if (! is_dir($_SESSION[APPCONFIG]->getValue('image','path')) || ! is_writable($_SESSION[APPCONFIG]->getValue('image','path')))
die(sprintf(_('The temporary path for JPGRAPH either doesnt exist or is not writable - you have it configured for %s.'),$_SESSION[APPCONFIG]->getValue('image','path')));
# When we get here, we have all the pre-reqs.
error_reporting(0);
require_once $jpgraph.'/src/jpgraph.php';
require_once $jpgraph.'/src/jpgraph_gantt.php';
require_once $jpgraph.'/src/jpgraph_line.php';
require_once $jpgraph.'/src/jpgraph_bar.php';
require_once $jpgraph.'/src/jpgraph_pie.php';
require_once $jpgraph.'/src/jpgraph_date.php';
error_reporting(E_ALL);
return true;
}
/**
* Put some HTML classes around strings containing values.
* @param string String to parse
* @param string Class to substitute
* @return string String with <span class=$class> around %s
*/
function classValue($string,$class) {
return preg_replace('/(\%[0-9.]*[sf])/',"<span class=\"$class\">$1</span>$2",$string);
}
function objectCache($object,$force=false) {
global $app;
$index = $app['server']->getIndex();
if (DEBUG_ENABLED)
debug_log('objectCache(): Entered with (%s,%s)',1,$object,isset($_SESSION['cache'][$index][$object]));
if (isset($_SESSION['cache'][$index][$object])) {
if ($_SESSION['cache'][$index][$object]->expired() || $force) {
if (DEBUG_ENABLED)
debug_log('objectCache(): Object expired (%s,%s)',1,$_SESSION['cache'][$index][$object]->cache,time());
$_SESSION['cache'][$index][$object]->load();
$_SESSION['cache'][$index][$object]->cache = time();
}
} else {
switch($object) {
case 'devclasses' :
$_SESSION['cache'][$index][$object] = new deviceClasses($index);
break;
case 'drives' :
$_SESSION['cache'][$index][$object] = new drives($index);
break;
case 'help' :
$_SESSION['cache'][$index][$object] = new help($index);
break;
case 'libraries' :
$_SESSION['cache'][$index][$object] = new libraries($index);
break;
case 'mgmtclasses' :
$_SESSION['cache'][$index][$object] = new mgmtClasses($index);
break;
case 'nodes' :
$_SESSION['cache'][$index][$object] = new nodes($index);
break;
case 'occupancy' :
$_SESSION['cache'][$index][$object] = new occupancy($index);
break;
case 'stgps' :
$_SESSION['cache'][$index][$object] = new storagePools($index);
break;
case 'summaryinfo' :
$_SESSION['cache'][$index][$object] = new summaryInfo($index);
break;
case 'volumes' :
$_SESSION['cache'][$index][$object] = new volumes($index);
break;
default:
error(sprintf('Unknown object %s',$object));
}
$_SESSION['cache'][$index][$object]->cache = time();
}
return $_SESSION['cache'][$index][$object];
}
function render_page($title,$body) {
$www = new page();
if (is_array($title)) {
foreach ($title as $key => $title) {
$block = new block();
$block->SetTitle($title);
$block->SetBody($body[$key]);
$www->block_add('body',$block);
}
} else {
$block = new block();
$block->SetTitle($title);
$block->SetBody($body);
$www->block_add('body',$block);
}
$www->body();
}
?>

49
lib/menu.php Normal file
View File

@ -0,0 +1,49 @@
<?php
// $Header: /cvsroot/phptsmadmin/phpTSMadmin/lib/menu.php,v 1.2 2009/04/19 04:03:05 wurley Exp $
/**
* @package leenooksApp
* @author Deon George
*
* Abstract class which represents the Menu view ; the draw() method
* must be implemented by subclasses
*
* @see Menu_HTML
*/
abstract class Menu {
# Datastore server represented by this tree
protected $index = null;
protected function __construct($index) {
$this->index = $index;
}
static public function getInstance($index) {
$menu = get_cached_item($index,'menu');
if (! $menu) {
$menu = $_SESSION[APPCONFIG]->getValue('appearance','menu');
eval('$menu = new '.$menu.'($index);');
set_cached_item($index,'menu','null',$menu);
}
return $menu;
}
/**
* Get the server Object for this tree
*
* @return object Server Object for this tree
*/
protected function getServer() {
return $_SESSION[APPCONFIG]->getServer($this->index);
}
public function getDatastore() {
return isset($_SESSION[APPCONFIG]->datastore->object[$this->index]) ? $_SESSION[APPCONFIG]->datastore->object[$this->index] : null;
}
/**
* Displays the Menu
*/
abstract public function draw();
}
?>

165
lib/menu_html.php Normal file
View File

@ -0,0 +1,165 @@
<?php
// $Header: /cvsroot/phptsmadmin/phpTSMadmin/lib/menu_html.php,v 1.4 2009/04/19 04:03:05 wurley Exp $
/**
* This class will render a HTML version of the Menu.
*
* @package leenooksApp
* @author Deon George
*/
class menu_html extends menu {
protected $javascript = '';
public function __construct($index) {
$this->index = $index;
$this->servers = $_SESSION[APPCONFIG]->servers->Instance($this->index);
}
/**
* Displays the menu in HTML
*/
public function draw() {
if (DEBUG_ENABLED)
debug_log('Entered with ()',33,__FILE__,__LINE__,__METHOD__);
echo '<table class="menu" border=0>';
$this->draw_server_name();
$this->javascript = '';
$javascript_id = 0;
# Is the user logged in, if so, show the menu.
if ($this->servers->isLoggedIn('user')) {
$this->draw_menu();
$this->draw_logged_in_user();
if ($this->servers->isReadOnly())
printf('<tr><td class="spacer"></td><td class="links" colspan="%s">(%s)</td></tr>',$this->getDepth()+3-1,_('read only'));
else
printf('<tr><td class="blank" colspan="%s">&nbsp;</td></tr>',$this->getDepth()+3);
# Draw the menu items.
foreach ($_SESSION[APPCONFIG]->getCommandList() as $command) {
printf('<tr class="option"><td class="expander"><img src="%s" /></td><td class="item"><a title="%s" href="cmd.php?cmd=%s&amp;index=%s">%s</a>',
'images/minus.png',$command['desc'],$command['default'],$this->servers->getIndex(),$command['summary']);
}
# User not logged in, show a login link.
} else {
$this->draw_login_link();
}
# Menu Footer.
# @todo: Need to implement a mechanism to have a footer, but not display it if it is blank.
#printf('<tr><td class="foot" colspan="%s">%s</td></tr>',$this->getDepth()+3,'&nbsp;');
echo '</table>';
echo "\n\n";
$this->draw_javascript();
}
protected function draw_server_name() {
echo '<tr class="server">';
printf('<td class="icon"><img src="images/server.png" alt="%s" /></td>',_('Server'));
printf('<td class="name" colspan="%s">',$this->getDepth()+3-1);
printf('%s',htmlspecialchars($this->servers->getValue('server','name')));
if ($this->servers->isLoggedIn('user')) {
$m = sprintf(_('Inactivity will log you off at %s'),
strftime('%H:%M',time() + ($this->servers->getValue('login','timeout')*60)));
printf(' <img width=14 height=14 src="images/timeout.png" title="%s" alt="%s"/>',$m,$m);
}
echo '</td></tr>';
}
protected function draw_menu() {
$links = '';
if (is_array($_SESSION[APPCONFIG]->getValue('menu','session')))
foreach ($_SESSION[APPCONFIG]->getValue('menu','session') as $link => $title) {
if ($link = $this->menu_item($link))
$links .= sprintf('<td class="ds_option">%s</td>',$link);
}
# Finally add our logout link.
$links .= sprintf('<td class="ds_option">%s</td>',$this->get_logout_menu_item());
# Draw the quick-links below the server name:
if ($links) {
printf('<tr class="links"><td class="spacer"></td><td colspan="%s">',$this->getDepth()+3-1);
printf('<table><tr>%s</tr></table>',$links);
echo '</td></tr>';
}
}
protected function menu_item($item) {
$menu = $_SESSION[APPCONFIG]->getValue('menu','session');
if (isset($menu[$item]))
return sprintf('<a title="%s" href="cmd.php?cmd=%s&amp;index=%s"><img src="%s%s" alt="%s" /><br />%s</a>',
$menu[$item]['text'],$menu[$item]['php'],$this->servers->getIndex(),IMGDIR,$menu[$item]['icon'],$item,$item);
else
return '&nbsp;';
}
protected function get_logout_menu_item() {
global $app;
$href = sprintf('cmd.php?cmd=logout&index=%s',$this->servers->getIndex());
return sprintf('<a title="%s" href="%s"><img src="%s" alt="%s" /><br />%s</a>',
_('Logout of this server'),htmlspecialchars($href),'images/logout.png',_('logout'),_('logout'));
}
protected function draw_logged_in_user() {
if (! is_null($_SESSION[APPCONFIG]->getValue('appearance','logged_in_chars'))
&& (strlen($this->servers->getLogin('user')) > $_SESSION[APPCONFIG]->getValue('appearance','logged_in_chars'))) {
printf('<tr><td class="spacer"></td><td class="logged_in" colspan="%s"><span style="white-space: nowrap;">%s%s <acronym title="%s"><b>%s</b>...</acronym></span></td></tr>',
$this->getDepth()+3-1,_('Logged in as'),_(':'),
$this->servers->getLogin('user'),
substr($this->servers->getLogin('user'),0,$_SESSION[APPCONFIG]->getValue('appearance','logged_in_chars')));
} else
printf('<tr><td class="spacer"></td><td class="logged_in" colspan="%s"><span style="white-space: nowrap;">%s%s <b>%s</b></span></td></tr>',
$this->getDepth()+3-1,_('Logged in as'),_(':'),$this->servers->getLogin('user'));
}
protected function draw_login_link() {
global $recently_timed_out_servers;
$server = $this->getServer();
$href = htmlspecialchars(
sprintf('cmd.php?cmd=%s&index=%s',get_custom_file($server->getIndex(),'login_form',''),$this->servers->getIndex()));
echo '<tr><td class="spacer"></td>';
printf('<td class="icon"><a href="%s"><img src="images/uid.png" alt="%s" /></a></td>',$href,_('login'));
printf('<td class="logged_in" colspan="%s"><a href="%s">%s</a></td>',$this->getDepth()+3-2,$href,_('Login').'...');
echo '</tr>';
printf('<tr><td class="blank" colspan="%s">&nbsp;</td>',$this->getDepth()+3);
printf('<tr><td class="blank" colspan="%s">&nbsp;</td>',$this->getDepth()+3);
# If the server recently timed out display the message
if (is_array($recently_timed_out_servers) && in_array($this->servers->getIndex(),$recently_timed_out_servers))
printf('<tr><td class="spacer"></td><td colspan="%s" class="links">%s</td></tr>',
$this->getDepth()+3-1,_('(Session timed out. Automatically logged out.)'));
}
protected function draw_javascript() {
if ($this->javascript) {
echo "<!-- Forms for javascript submit to call to create base_dns -->\n";
echo $this->javascript;
echo "<!-- The end of the forms for javascript submit to call to create base_dns -->\n";
}
}
/**
* Work out how long the deepest "opened" menu item is.
* This is used to dynamically build our cells for our menu table.
*/
protected function getDepth() {
return 1;
}
}
?>

504
lib/page.php Normal file
View File

@ -0,0 +1,504 @@
<?php
// $Header: /cvsroot/phptsmadmin/phpTSMadmin/lib/page.php,v 1.6 2009/04/19 04:03:05 wurley Exp $
/**
* Page Rendering Functions
*
* @author Deon George (c) 2009
* @package leenooksApp
*/
/**
* This class controls the final output to the browser.
*
* @package leenooksApp
* @subpackage Page
*/
class page {
# pre-HTML headers
protected $_pageheader;
# Items to get into the <head>
protected $_head;
# Settings for this application
protected $_app;
# Default values array.
protected $_default;
public function __construct($index=null) {
if (defined('DEBUG_ENABLED') && DEBUG_ENABLED)
debug_log('Entered with [%s]',129,__FILE__,__LINE__,__METHOD__,$index);
# To be defined in a configuration file.
$this->_app['title'] = app_name();
# Default Values for configurable items.
$this->_default['stylecss'] = CSSDIR.'style.css';
$this->_default['logo'] = IMGDIR.'logo-small.png';
$this->_default['sysmsg']['error'] = IMGDIR.'error-big.png';
$this->_default['sysmsg']['warn'] = IMGDIR.'warn-big.png';
$this->_default['sysmsg']['info'] = IMGDIR.'info-big.png';
# Capture any output so far (in case we send some headers below) - there shouldnt be any output anyway.
$preOutput = '';
# Try and work around if php compression is on, or the user has set compression in the config.
# type = 1 for user gzip, 0 for php.ini gzip.
$obStatus = ob_get_status();
if (isset($obStatus['type']) && $obStatus['type'] && $obStatus['status']) {
$preOutput = ob_get_contents();
ob_end_clean();
}
header('Content-type: text/html; charset="UTF-8"');
if (isCompress()) {
header('Content-Encoding: gzip');
if (DEBUG_ENABLED)
debug_log('Sent COMPRESSED header to browser and discarded (%s)',129,__FILE__,__LINE__,__METHOD__,$preOutput);
}
if (isset($_SESSION[APPCONFIG])
&& $_SESSION[APPCONFIG]->getValue('appearance','compress')
&& ini_get('zlib.output_compression'))
$this->setsysmsg(array('title'=>_('Warning'),'body'=>_('WARNING: You cannot have PHP compression and application compression enabled at the same time. Please unset zlib.output_compression or set $config->custom->appearance[\'compress\']=false'),'type'=>'warn'));
# Turn back on output buffering.
ob_start();
# Initial Values
$this->_pageheader[] .= '<?xml version="1.0" encoding="utf-8"?>'."\n";
$this->_pageheader[] .= '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML Basic 1.0//EN"'."\n";
$this->_pageheader[] .= '"http://www.w3.org/TR/xhtml-basic/xhtml-basic10.dtd">'."\n";
$this->_pageheader[] .= "\n";
$this->_pageheader[] .= '<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="auto" lang="auto" dir="ltr">'."\n";
$this->_pageheader[] .= "\n";
$this->_app['logo'] = $this->_default['logo'];
if (! is_null($index))
$this->_app['urlcss'] = sprintf('%s%s',CSSDIR,$_SESSION[APPCONFIG]->getValue('appearance','stylesheet'));
else
$this->_app['urlcss'] = sprintf('%s%s',CSSDIR,'style.css');
$this->index = $index;
}
/* Add to the HTML Header */
public function head_add($html) {
$this->_head[] .= $html;
}
/* Print out the HTML header */
private function pageheader_print() {
if (defined('DEBUG_ENABLED') && DEBUG_ENABLED)
debug_log('Entered with ()',129,__FILE__,__LINE__,__METHOD__);
# HTML prepage requirements.
foreach ($this->_pageheader as $line)
echo $line."\n";
# Page Title
echo '<head>';
if (isset($_SESSION[APPCONFIG]))
printf('<title>%s (%s) - %s</title>',
$this->_app['title'],app_version(),$_SESSION[APPCONFIG]->getValue('appearance','page_title'));
else
printf('<title>%s - %s</title>',$this->_app['title'],app_version());
# Style sheet.
printf('<link type="text/css" rel="stylesheet" href="%s" />',$this->_app['urlcss']);
printf('<link rel="shortcut icon" href="%s/favicon.ico" type="image/vnd.microsoft.icon" />',IMGDIR);
if (defined('JSDIR')) {
echo "\n";
printf('<script type="text/javascript" src="%smenu_hide.js"></script>',JSDIR);
echo "\n";
}
# HTML head requirements.
if (is_array($this->_head) && count ($this->_head))
foreach ($this->_head as $line)
echo $line."\n";
echo '</head>';
echo "\n";
}
private function head_print() {
if (defined('DEBUG_ENABLED') && DEBUG_ENABLED)
debug_log('Entered with ()',129,__FILE__,__LINE__,__METHOD__);
if (isset($_SESSION[APPCONFIG]))
$pagetitle = $_SESSION[APPCONFIG]->getValue('appearance','page_title') ? ' - '.$_SESSION[APPCONFIG]->getValue('appearance','page_title') : '';
else
$pagetitle = '';
echo '<tr class="pagehead">';
echo '<td colspan=3><div id="ajHEAD"><table border=0><tr>';
printf('<td align="left"><a href="%s" target="_blank"><img src="%s" alt="Logo" class="logo" /></a></td>','#',$this->_app['logo']);
echo '<td align="right" class="imagetop">';
$empty = true;
if (function_exists('cmd_control_pane'))
foreach (cmd_control_pane('top') as $cmd => $cmddetails) {
$cmds = preg_split('/:/',$cmd);
if (defined('APPCONFIG') && isset($_SESSION[APPCONFIG]) && method_exists($_SESSION[APPCONFIG],'isCommandAvailable'))
if ($_SESSION[APPCONFIG]->isCommandAvailable('all',$cmds)) {
if ((isset($cmddetails['enable']) && trim($cmddetails['enable'])) || ! isset($cmddetails['enable'])) {
if (! $empty)
echo ' ';
printf('<a %s>%s</a>',$cmddetails['link'],$cmddetails['image']);
$empty = false;
}
}
}
if ($empty)
echo '&nbsp;';
echo '</td>';
echo '</tr></table></div></td>';
echo '</tr>';
echo "\n";
}
private function control_print() {
if (defined('DEBUG_ENABLED') && DEBUG_ENABLED)
debug_log('Entered with ()',129,__FILE__,__LINE__,__METHOD__);
echo '<table class="control" border=0>';
echo '<tr><td>';
$empty = true;
if (function_exists('cmd_control_pane'))
foreach (cmd_control_pane('main') as $cmd => $cmddetails) {
$cmds = preg_split('/:/',$cmd);
if (defined('APPCONFIG') && isset($_SESSION[APPCONFIG]) && method_exists($_SESSION[APPCONFIG],'isCommandAvailable'))
if ($_SESSION[APPCONFIG]->isCommandAvailable('all',$cmds)) {
if ((isset($cmddetails['enable']) && trim($cmddetails['enable'])) || ! isset($cmddetails['enable'])) {
if (! $empty)
echo ' | ';
printf('<a %s>%s</a>',$cmddetails['link'],
$_SESSION[APPCONFIG]->getValue('appearance','control_icons') ? $cmddetails['image'] : $cmddetails['title']);
$empty = false;
}
}
}
echo '</td>';
if ($empty)
echo '<td>&nbsp;</td>';
echo '</tr>';
echo '</table>';
}
protected function menu() {
if (defined('DEBUG_ENABLED') && DEBUG_ENABLED)
debug_log('Entered with ()',129,__FILE__,__LINE__,__METHOD__);
if (! isset($_SESSION[APPCONFIG]))
return;
if (is_null($this->index))
$this->index = min(array_keys($_SESSION[APPCONFIG]->getServerList()));
if (count($_SESSION[APPCONFIG]->getServerList()) > 1) {
echo '<form name="server_select" action="cmd.php" method="post">';
echo '<table class="server_select"><tr><td>';
printf('%s%s<br />%s',_('Server Select'),_(':'),
server_select_list($this->index,false,'index',true,sprintf("onchange=\"menu_unhide('index',%s)\"",$this->index)));
echo '</td></tr></table>';
echo '</form>';
echo "\n\n";
}
foreach ($_SESSION[APPCONFIG]->getServerList() as $index => $server) {
printf('<div id="SID_%s" style="display: %s">',$server->getIndex(),($server->getIndex() == $this->index) ? 'block' : 'none');
$menu = menu::getInstance($server->getIndex());
$menu->draw();
echo '</div>';
echo "\n\n";
}
}
public function block_add($side,$object) {
if (! is_object($object))
error(sprintf('block_add called with [%s], but it is not an object',serialize($object)));
$this->_block[$side][] = $object;
}
private function block_print($side) {
if (defined('DEBUG_ENABLED') && DEBUG_ENABLED)
debug_log('Entered with ()',129,__FILE__,__LINE__,__METHOD__);
if (! isset($this->_block[$side]))
return;
printf('<td class="%s" colspan=2>',$side);
foreach ($this->_block[$side] as $object)
echo $object->draw($side);
echo '</td>';
}
private function sysmsg() {
if (defined('DEBUG_ENABLED') && DEBUG_ENABLED)
debug_log('Entered with ()',129,__FILE__,__LINE__,__METHOD__);
if (isset($this->sysmsg)) {
foreach ($this->sysmsg as $index => $details) {
switch ($details['type']) {
case 'error':
$icon = $this->_default['sysmsg']['error'];
break;
case 'warn':
$icon = $this->_default['sysmsg']['warn'];
break;
case 'info':
default:
$icon = $this->_default['sysmsg']['info'];
break;
}
if (isset($details['title']))
printf('<tr><td class="icon" rowspan=2 align="right"><img src="%s" alt="%s" /></td><td class="head" align="right">%s</td></tr>',
$icon,$details['type'],$details['title']);
if (isset($details['body']))
if (is_array($details['body'])) {
echo '<tr><td class="body">';
foreach ($details['body'] as $line)
printf('%s<br />',$line);
echo '</td></tr>';
} else
printf('<tr><td class="body">%s</td></tr>',$details['body']);
}
}
}
public function body() {
if (defined('DEBUG_ENABLED') && DEBUG_ENABLED)
debug_log('Entered with ()',129,__FILE__,__LINE__,__METHOD__);
# Add the Session System Messages
if (isset($_SESSION['sysmsg']) && is_array($_SESSION['sysmsg'])) {
foreach ($_SESSION['sysmsg'] as $msg)
$this->setsysmsg($msg);
unset($_SESSION['sysmsg']);
}
if (isset($this->sysmsg)) {
echo '<table class="sysmsg">';
$this->sysmsg();
echo '</table>';
echo "\n";
}
if (isset($this->_block['body'])) {
foreach ($this->_block['body'] as $object)
echo $object->draw('body');
}
}
private function footer_print() {
if (defined('DEBUG_ENABLED') && DEBUG_ENABLED)
debug_log('Entered with ()',129,__FILE__,__LINE__,__METHOD__);
printf('<tr class="foot"><td><small>%s</small></td><td colspan=2><div id="ajFOOT">%s</div>%s</td></tr>',
isCompress() ? '[C]' : '&nbsp;',
app_version(),
'');
}
/**
* Only show a particular page frame - used by an AJAX call
*/
public function show($frame,$compress=false) {
if (defined('DEBUG_ENABLED') && DEBUG_ENABLED)
debug_log('Entered with (%s)',129,__FILE__,__LINE__,__METHOD__,$compress);
# If the body is called via AJAX, and compression is enable, we need to compress the output
if ($compress && ob_get_level() && isCompress()) {
ob_end_clean();
ob_start();
}
switch ($frame) {
case 'BODY' :
$this->body();
break;
case 'MENU' :
$this->menu();
break;
default :
error(sprintf('show called with unknown frame [%s]',$frame),'error','index.php');
}
if ($compress && ob_get_level() && isCompress()) {
$output = ob_get_contents();
ob_end_clean();
if (DEBUG_ENABLED)
debug_log('Sending COMPRESSED output to browser[(%s),%s]',129,__FILE__,__LINE__,__METHOD__,
strlen($output),$output);
print gzencode($output);
}
}
public function display($filter=array()) {
if (defined('DEBUG_ENABLED') && DEBUG_ENABLED)
debug_log('Entered with [%s]',129,__FILE__,__LINE__,__METHOD__,$filter);
# Control what is displayed.
$display = array(
'HEAD'=>true,
'CONTROL'=>true,
'MENU'=>true,
'FOOT'=>true
);
$display = array_merge($display,$filter);
# HTML Header
$this->pageheader_print();
# Start of body
# Page Header
echo '<body>';
echo "\n";
echo '<table class="page" border=0 width=100%>';
if ($display['HEAD'])
$this->head_print();
# Control Line
if ($display['CONTROL']) {
echo '<tr class="control"><td colspan=3>';
echo '<div id="ajCONTROL">';
$this->control_print();
echo '</div></td></tr>';
echo "\n";
}
# Left Block
echo '<tr>';
if ($display['MENU']) {
echo '<td class="menu" colspan=2>';
echo '<div id="ajMENU">';
$this->menu();
echo '</div>';
echo '</td>';
}
echo '<td class="body" width=80%>';
echo '<div id="ajBODY">';
echo "\n";
$this->body();
echo '</div>';
echo '</td>';
echo '</tr>';
echo "\n";
# Page Footer
if ($display['FOOT'])
$this->footer_print();
# Finish HTML
echo '</table>';
echo '</body>';
echo '</html>';
# compress output
if (ob_get_level() && isCompress()) {
$output = ob_get_contents();
ob_end_clean();
if (DEBUG_ENABLED)
debug_log('Sending COMPRESSED output to browser[(%s),%s]',129,__FILE__,__LINE__,__METHOD__,
strlen($output),$output);
print gzencode($output);
}
}
public function setsysmsg($data) {
if (defined('DEBUG_ENABLED') && DEBUG_ENABLED)
debug_log('Entered with [%s]',129,__FILE__,__LINE__,__METHOD__,$data);
if (! is_array($data))
return;
if (isset($this->sysmsg))
$msgnum = count($this->sysmsg) + 1;
else
$msgnum = 1;
foreach (array('title','body','type') as $index)
if (isset($data[$index]))
$this->sysmsg[$msgnum][$index] = $data[$index];
}
}
/**
* This class draws a block.
*
* @package leenooksApp
* @subpackage Page
*/
class block {
private $title;
private $body;
private $foot;
public function __construct() {
}
public function setTitle($html) {
$this->title = $html;
}
public function setBody($html) {
$this->body = $html;
}
public function setFooter($html) {
$this->foot = $html;
}
public function draw($side) {
$output = '';
$output .= sprintf('<table class="%s">',$side);
if (isset($this->body['title']))
$output .= sprintf('<tr><td class="head">%s</td></tr>',$this->title);
if (isset($this->body['body']))
$output .= sprintf('<tr><td>%s</td></tr>',$this->body);
if (isset($this->body['footer']))
$output .= sprintf('<tr><td class="foot">%s</td></tr>',$this->foot);
$output .= '</table>';
return $output;
}
}
?>

21
lib/page_pta.php Normal file
View File

@ -0,0 +1,21 @@
<?php
// $Header: /cvsroot/phptsmadmin/phpTSMadmin/lib/page_pta.php,v 1.1 2008/01/13 08:05:12 wurley Exp $
/**
* Page Rendering Functions
*
* @package phpTSMadmin
*/
class page_pta extends page {
public function __construct() {
parent::__construct();
if (defined('DEBUG_ENABLED') && DEBUG_ENABLED)
debug_log('Entered with [%s]',129,__FILE__,__LINE__,__METHOD__,$server_id);
# To be defined in a configuration file.
$this->_app['title'] = 'phpTSMadmin';
}
}
?>

185
lib/session_functions.php Normal file
View File

@ -0,0 +1,185 @@
<?php
// $Header: /cvsroot/phptsmadmin/phpTSMadmin/lib/session_functions.php,v 1.4 2009/04/19 03:51:30 wurley Exp $
/**
* A collection of functions to handle sessions.
*
* @author Deon George (c) 2009
* @package leenooksApp
* @subpackage Session
*/
/** The session ID that this application will use for all sessions */
define('APP_SESSION_ID','APPSESSID');
/** Enables session paranoia, which causes SIDs to change each page load (EXPERIMENTAL!) */
define('app_session_id_paranoid', false);
/** Flag to indicate whether the session has already been initialized (this constant gets stored in $_SESSION) */
define('app_session_id_init', 'app_initialized');
/** The minimum first char value IP in hex for IP hashing. */
define('app_session_id_ip_min', 8);
/** The maximum first char value of the IP in hex for IP hashing. */
define('app_session_id_ses_max', 36);
/**
* Creates a new session id, which includes an IP hash.
*
* @return string the new session ID string
*/
function app_session_get_id() {
if (DEBUG_ENABLED)
debug_log('Entered with ()',1,__FILE__,__LINE__,__METHOD__);
$id_md5 = md5(rand(1,1000000));
$ip_md5 = md5($_SERVER['REMOTE_ADDR']);
$id_hex = hexdec($id_md5[0]) + 1;
$ip_hex = hexdec($ip_md5[0]);
if ($ip_hex <= app_session_id_ip_min)
$ip_len = app_session_id_ip_min;
else
$ip_len = $ip_hex - 1;
$new_id = substr($id_md5, 0, $id_hex) .
substr($ip_md5, $ip_hex, $ip_len) .
substr($id_md5, $id_hex, app_session_id_ses_max - ($id_hex + $ip_len));
return $new_id;
}
/**
* Checks if the session belongs to an IP
*
* @return boolean True, if the session is valid
*/
function app_session_verify_id() {
if (DEBUG_ENABLED)
debug_log('Entered with ()',1,__FILE__,__LINE__,__METHOD__);
$check_id = session_id();
$ip_md5 = md5($_SERVER['REMOTE_ADDR']);
$id_hex = hexdec($check_id[0]) + 1;
$ip_hex = hexdec($ip_md5[0]);
if ($ip_hex <= app_session_id_ip_min)
$ip_len = app_session_id_ip_min;
else
$ip_len = $ip_hex - 1;
$ip_ses = substr($check_id, $id_hex, $ip_len);
$ip_ver = substr($ip_md5, $ip_hex, $ip_len);
return ($ip_ses == $ip_ver);
}
function app_session_param() {
/* If cookies were disabled, build the url parameter for the session id.
* It will be append to the url to be redirect */
return (SID != '') ? sprintf('&%s=%s',session_name(),session_id()) : '';
}
/**
* The only function which should be called by a user
*
* @see common.php
* @see APP_SESSION_ID
* @return boolean Returns true if the session was started the first time
*/
function app_session_start() {
$sysmsg = null;
# If we have a sysmsg before our session has started, then preserve it.
if (isset($_SESSION['sysmsg']))
$sysmsg = $_SESSION['sysmsg'];
/* If session.auto_start is on in the server's PHP configuration (php.ini), then
* we will have problems loading our schema cache since the session will have started
* prior to loading the SchemaItem (and descedants) class. Destroy the auto-started
* session to prevent this problem.
*/
if (ini_get('session.auto_start'))
@session_destroy();
# Do we already have a session?
if (@session_id())
return;
@session_name(APP_SESSION_ID);
@session_start();
# Do we have a valid session?
$is_initialized = is_array($_SESSION) && array_key_exists(app_session_id_init,$_SESSION);
if (! $is_initialized) {
if (app_session_id_paranoid) {
ini_set('session.use_trans_sid',0);
@session_destroy();
@session_id(app_session_get_id());
@session_start();
ini_set('session.use_trans_sid',1);
}
$_SESSION[app_session_id_init]['name'] = app_name();
$_SESSION[app_session_id_init]['version'] = app_version();
$_SESSION[app_session_id_init]['config'] = filemtime(CONFDIR.'config.php');
}
@header('Cache-control: private'); // IE 6 Fix
if (app_session_id_paranoid && ! app_session_verify_id())
error('Session inconsistent or session timeout','error','index.php');
# Check we have the correct version of the SESSION cache
if (isset($_SESSION['cache']) || isset($_SESSION[app_session_id_init])) {
if (! is_array($_SESSION[app_session_id_init])) $_SESSION[app_session_id_init] = array();
if (! isset($_SESSION[app_session_id_init]['version']) || ! isset($_SESSION[app_session_id_init]['config']) || ! isset($_SESSION[app_session_id_init]['name'])
|| $_SESSION[app_session_id_init]['name'] !== app_name()
|| $_SESSION[app_session_id_init]['version'] !== app_version()
|| $_SESSION[app_session_id_init]['config'] != filemtime(CONFDIR.'config.php')) {
$_SESSION[app_session_id_init]['name'] = app_name();
$_SESSION[app_session_id_init]['version'] = app_version();
$_SESSION[app_session_id_init]['config'] = filemtime(CONFDIR.'config.php');
unset($_SESSION['cache']);
unset($_SESSION['USER']);
unset($_SESSION[APPCONFIG]);
# Our configuration information has changed, so we'll redirect to index.php to get it reloaded again.
system_message(array(
'title'=>_('Configuration cache stale.'),
'body'=>_('Your configuration has been automatically refreshed.'),
'type'=>'info','special'=>true));
$config_file = CONFDIR.'config.php';
$config = check_config($config_file);
if (! $config)
debug_dump_backtrace('config is empty?',1);
} else {
# Sanity check, specially when upgrading from a previous release.
if (isset($_SESSION['cache']))
foreach (array_keys($_SESSION['cache']) as $id)
if (isset($_SESSION['cache'][$id]['tree']['null']) && ! is_object($_SESSION['cache'][$id]['tree']['null']))
unset($_SESSION['cache'][$id]);
}
}
# If we came via index.php, then set our $config.
if (! isset($_SESSION[APPCONFIG]) && isset($config))
$_SESSION[APPCONFIG] = $config;
# Restore our sysmsg's if there were any.
if ($sysmsg) {
if (! isset($_SESSION['sysmsg']) || ! is_array($_SESSION['sysmsg']))
$_SESSION['sysmsg'] = array();
array_push($_SESSION['sysmsg'],$sysmsg);
}
}
/**
* Stops the current session.
*/
function app_session_close() {
@session_write_close();
}
?>

1906
lib/tsm_classes.php Normal file

File diff suppressed because it is too large Load Diff

15
tools/unserialize.php Normal file
View File

@ -0,0 +1,15 @@
<?php
require '../lib/common.php';
if ($var = get_request('var','REQUEST')) {
debug_dump($var);
debug_dump(unserialize($var));
} else {
echo '<form>';
echo '<input type="text" name="var" />';
echo '<input type="submit" />';
echo '</form>';
}
?>