oracletool.pl
上传用户:abclishi
上传日期:2007-01-07
资源大小:99k
文件大小:435k
源码类别:

Oracle数据库

开发平台:

Perl

  1.    $sql = "$copyright
  2. SELECT
  3.    COLUMN_NAME                                  "Column name",
  4.    DATA_TYPE                                    "Type",
  5.    DATA_LENGTH                                  "Length"
  6. FROM DBA_TAB_COLUMNS
  7.    WHERE TABLE_NAME = '$object_name'
  8.    AND OWNER = '$schema'
  9. ORDER BY COLUMN_ID
  10. ";
  11.    $object_type = lc $object_type;
  12.    $text = "Structure of $object_type $object_name";
  13.    $link = "";
  14.    DisplayTable($sql,$text,$link);
  15.    $sql = "$copyright
  16. SELECT
  17.    SYNONYM_NAME                 "Synonym name",
  18.    OWNER                        "Owner",
  19.    DB_LINK                      "DB link"
  20. FROM DBA_SYNONYMS
  21.    WHERE TABLE_NAME = '$object_name'
  22.    AND TABLE_OWNER = '$schema'
  23. ";
  24.    $text = "Synonyms pointing to this view.";
  25.    $link = "";
  26.    $infotext = "There are no synonyms pointing to this view.";
  27.    DisplayTable($sql,$text,$link,$infotext);
  28. # View source
  29.    $sql = "$copyright
  30. SELECT 
  31.    TEXT "Text"
  32. FROM DBA_VIEWS 
  33.    WHERE VIEW_NAME = '$object_name' 
  34.    AND OWNER = '$schema'";
  35.    $text = "Text: $object_type $object_name";
  36.    DisplayPiecedData($sql,$text);
  37.    logit("Exit subroutine showView");
  38. }
  39. sub checkValidity {
  40.    logit("Enter subroutine checkValidity");
  41.    my ($sql,$cursor,$status,$text);
  42.    # Check for validity. If invalid, show additional info.
  43.    $object_type = uc($object_type);
  44.    $sql = "$copyright
  45. SELECT
  46.    STATUS
  47. FROM DBA_OBJECTS
  48.    WHERE OBJECT_NAME = '$object_name'
  49.    AND OBJECT_TYPE = '$object_type'
  50.    AND OWNER = '$schema'
  51. ";
  52.    $cursor = $dbh->prepare($sql);
  53.    $cursor->execute;
  54.    $status = $cursor->fetchrow_array;
  55.    $cursor->finish;
  56.    if ($status eq "INVALID") {
  57.       $sql = "$copyright
  58. SELECT
  59.    LINE         "Line",
  60.    POSITION     "Position",
  61.    TEXT         "Text"
  62. FROM DBA_ERRORS
  63.    WHERE NAME = '$object_name'
  64.    AND TYPE = '$object_type'
  65.    AND OWNER = '$schema'
  66. ORDER BY SEQUENCE
  67. ";
  68.       $text = "Errors";
  69.       DisplayTable($sql,$text);
  70.    }
  71.    logit("Enter subroutine checkValidity");
  72. }
  73. sub showTrigger {
  74.    logit("Enter subroutine showTrigger");
  75.    my ($sql,$text,$link);
  76. # General info
  77. $sql = "$copyright
  78. SELECT 
  79.    TRIGGER_NAME "Trigger name",
  80.    TRIGGER_TYPE "Trigger type",
  81.    TRIGGERING_EVENT "Triggering event",
  82.    REFERENCING_NAMES "Referencing names",
  83.    WHEN_CLAUSE "When clause",
  84.    STATUS "Status"
  85. FROM DBA_TRIGGERS
  86.    WHERE TRIGGER_NAME = '$object_name'
  87.    AND OWNER = '$schema'
  88. ";
  89.    $text = "Trigger: $object_name";
  90.    DisplayTable($sql,$text,$link);
  91.    checkValidity();
  92. # Source
  93. $sql = "$copyright
  94. SELECT
  95.     TRIGGER_BODY "Trigger body"
  96. FROM DBA_TRIGGERS
  97.    WHERE TRIGGER_NAME = '$object_name'
  98. AND OWNER = '$schema'
  99. ";
  100.    $text = "Trigger body";
  101.    DisplayPiecedData($sql,$text);
  102.    logit("Exit subroutine showTrigger");
  103. }
  104. sub showDBlink() {
  105.    logit("Enter subroutine showDBlink");
  106.    my ($sql,$text,$link);
  107. # General info
  108.    $sql = "$copyright
  109. SELECT 
  110.    DB_LINK "Link name", 
  111.    USERNAME "Username", 
  112.    HOST "Host", 
  113.    CREATED "Created" 
  114. FROM DBA_DB_LINKS 
  115.    WHERE DB_LINK = '$object_name' 
  116.    AND OWNER = '$schema'"
  117. ;
  118.    $text = "Database link: $object_name";
  119.    $link = "";
  120.    DisplayTable($sql,$text,$link);
  121.    logit("Exit subroutine showDBlink");
  122. }
  123. sub showSource() {
  124.    logit("Enter subroutine showSource");
  125.    my ($sql,$cursor,$status,$text,$infotext,$link);
  126.    showGrantButton();
  127. # General info
  128.    $sql = "$copyright
  129. SELECT
  130.    TO_CHAR(CREATED,'Month DD, YYYY - HH24:MI')          "Date created",
  131.    TO_CHAR(LAST_DDL_TIME,'Month DD, YYYY - HH24:MI')    "Last compiled",
  132.    STATUS "Status"
  133. FROM DBA_OBJECTS
  134.    WHERE OBJECT_NAME = '$object_name'
  135.    AND OBJECT_TYPE = '$object_type'
  136.    AND OWNER = '$schema'
  137. ";
  138.    $text = "General info: $object_type $object_name";
  139.    DisplayTable($sql,$text);
  140.    checkValidity();
  141.    $sql = "$copyright
  142. SELECT
  143.    SYNONYM_NAME                 "Synonym name",
  144.    OWNER                        "Owner",
  145.    DB_LINK                      "DB link"
  146. FROM DBA_SYNONYMS
  147.    WHERE TABLE_NAME = '$object_name'
  148.    AND TABLE_OWNER = '$schema'
  149. ";
  150.    $text = "Synonyms pointing to this object.";
  151.    $link = "";
  152.    $infotext = "There are no synonyms pointing to this object.";
  153.    DisplayTable($sql,$text,$link,$infotext);
  154. # Source of object (package, procedure, etc.)
  155.    $sql = "$copyright
  156. SELECT 
  157.    TEXT
  158. FROM 
  159.    DBA_SOURCE 
  160. WHERE TYPE = '$object_type' 
  161.    AND OWNER = '$schema' 
  162.    AND NAME = '$object_name' 
  163. ORDER BY LINE
  164. ";
  165.    $text = "Text: $object_type $object_name";
  166.    $link = "";
  167.    DisplayPiecedData($sql,$text,$link);
  168.    logit("Exit subroutine showSource");
  169. }
  170. sub showSequence() {
  171.    my ($sql,$text,$link);
  172.    logit("Enter subroutine showSequence");
  173.    showGrantButton();
  174. # General info
  175.    $sql = "$copyright
  176. SELECT 
  177.    MIN_VALUE "Min value", 
  178.    MAX_VALUE "Max value", 
  179.    INCREMENT_BY "Increment by", 
  180.    CYCLE_FLAG "Cycle flag", 
  181.    ORDER_FLAG "Order flag", 
  182.    CACHE_SIZE "Cache size", 
  183.    LAST_NUMBER "Last number" 
  184. FROM DBA_SEQUENCES 
  185.    WHERE SEQUENCE_NAME = '$object_name' 
  186.    AND SEQUENCE_OWNER = '$schema'
  187. ";
  188.    $text = "$object_type $object_name";
  189.    $link = "";
  190.    DisplayTable($sql,$text,$link);
  191.    logit("Enter subroutine showSequence");
  192. }
  193. sub showGrantsto() {
  194.    my ($sql,$text,$link,$infotext);
  195.    logit("Enter subroutine showGrantsto");
  196. # System privileges
  197.    $sql = "$copyright
  198. SELECT 
  199.    PRIVILEGE "Privilege", 
  200.    ADMIN_OPTION "Admin option"
  201. FROM DBA_SYS_PRIVS 
  202.    WHERE GRANTEE = '$schema'
  203. ";
  204.    $text = "System privileges granted to $schema";
  205.    $link = "";
  206.    $infotext = "There are no system privileges granted to $schema.";
  207.    DisplayTable($sql,$text,$link,$infotext);
  208. # Granted roles
  209.    $sql = "$copyright
  210. SELECT 
  211.    GRANTED_ROLE "Granted role", 
  212.    ADMIN_OPTION "Admin option", 
  213.    DEFAULT_ROLE "Default role" 
  214. FROM DBA_ROLE_PRIVS 
  215.    WHERE GRANTEE = '$schema'
  216. ";
  217.    $text = "Roles granted to $schema";
  218.    $link = "$scriptname?database=$database&schema=$schema&object_type=ROLES";
  219.    $infotext = "There are no roles granted to $schema.";
  220.    DisplayTable($sql,$text,$link,$infotext);
  221. # Granted object privileges (explicit)
  222.    $sql = "$copyright
  223. SELECT 
  224.    PRIVILEGE "Privilege", 
  225.    TABLE_NAME "Table name", 
  226.    GRANTOR "Grantor", 
  227.    GRANTABLE "Grantable" 
  228. FROM DBA_TAB_PRIVS 
  229.    WHERE GRANTEE = '$schema' 
  230. ORDER BY GRANTOR, TABLE_NAME
  231. ";
  232.    $text = "Explicit grants to $schema";
  233.    $link = "";
  234.    $infotext = "There are no explicit grants to $schema.";
  235.    DisplayTable($sql,$text,$link,$infotext);
  236.    logit("Exit subroutine showGrantsto");
  237. }
  238. sub showRoles {
  239.    logit("Enter subroutine showRoles");
  240.    my ($sql,$text,$link,$infotext);
  241.    $sql = "$copyright
  242. SELECT
  243.    GRANTEE "Granted user"
  244. FROM DBA_ROLE_PRIVS
  245.    WHERE GRANTED_ROLE = '$object_name'
  246.    AND GRANTEE IN (
  247. SELECT USERNAME 
  248.    FROM DBA_USERS
  249. )
  250. ";
  251.    $text = "Users which are granted this role.";
  252.    $link = "$scriptname?database=$database&object_type=USERINFO";
  253.    $infotext = "No users are granted this role.";
  254.    DisplayColTable($sql,$text,$link,$infotext,$schema_cols);
  255.    $sql = "$copyright
  256. SELECT
  257.    GRANTEE "Granted user"
  258. FROM DBA_ROLE_PRIVS
  259.    WHERE GRANTED_ROLE = '$object_name'
  260.    AND GRANTEE IN (
  261. SELECT ROLE 
  262.    FROM DBA_ROLES
  263. )
  264. ";
  265.    $text = "Roles which are granted this role.";
  266.    $link = "";
  267.    $infotext = "No roles are granted this role.";
  268.    DisplayTable($sql,$text,$link,$infotext);
  269. # Roles granted to this role
  270.    $sql = "$copyright
  271. SELECT 
  272.    GRANTED_ROLE "Granted role", 
  273.    ADMIN_OPTION "Admin option", 
  274.    DEFAULT_ROLE "Default role" 
  275. FROM DBA_ROLE_PRIVS 
  276.    WHERE GRANTEE = '$object_name'
  277. ";
  278.    $text = "Roles granted to role $object_name"; 
  279.    $link = "$scriptname?database=$database&object_type=ROLES"; 
  280.    $infotext = "There are no roles granted to this role.";
  281.    DisplayTable($sql,$text,$link,$infotext);
  282. # System privileges granted to this role
  283.    $sql = "$copyright
  284. SELECT 
  285.    PRIVILEGE "Privilege", 
  286.    ADMIN_OPTION "Admin option" 
  287. FROM DBA_SYS_PRIVS 
  288.    WHERE GRANTEE = '$object_name' 
  289. ORDER BY PRIVILEGE
  290. ";
  291.    $text = "System privileges granted to role $object_name";
  292.    $link = "";
  293.    $infotext = "There are no system privileges granted to this role.";
  294.    DisplayTable($sql,$text,$link,$infotext);
  295. # Object privileges granted to this role
  296.    $sql = "$copyright
  297. SELECT 
  298.    PRIVILEGE "Privilege", 
  299.    TABLE_NAME "Table name", 
  300.    GRANTOR "Grantor", 
  301.    GRANTABLE "Grantable?" 
  302. FROM DBA_TAB_PRIVS 
  303.    WHERE GRANTEE = '$object_name' 
  304. ORDER BY GRANTOR, TABLE_NAME
  305. ";
  306.    $text = "Object privileges granted to role $object_name";
  307.    $link = "";
  308.    $infotext = "There are no object privileges granted to this role.";
  309.    DisplayTable($sql,$text,$link,$infotext);
  310.    logit("Exit subroutine showRoles");
  311. }
  312. sub showGrantsfrom {
  313.    logit("Enter subroutine showGrantsfrom");
  314.    my ($sql,$text,$link,$infotext);
  315.  
  316. # Object privileges granted from this user
  317.    $sql = "$copyright
  318. SELECT 
  319.    GRANTEE, 
  320.    PRIVILEGE, 
  321.    TABLE_NAME, 
  322.    GRANTABLE 
  323. FROM DBA_TAB_PRIVS 
  324.    WHERE GRANTOR = '$schema' 
  325. ORDER BY GRANTEE, TABLE_NAME
  326. ";
  327.    $text = "Object privileges granted from user $schema";
  328.    $link = "";
  329.    $infotext = "$schema has not granted any privileges to other users. $schema is a stingy user.";
  330.    DisplayTable($sql,$text,$link,$infotext);
  331.    logit("Exit subroutine showGrantsfrom");
  332. }
  333. sub OPSpage {
  334.    logit("Enter subroutine OPSpage");
  335.    my ($sql,$cursor,$text,$link,$infotext);
  336.    my ($instance_name,$instance_number,$thread,$hostname,$startup_time);
  337. # Local instance info
  338.    $sql = "$copyright
  339. SELECT 
  340.    INSTANCE_NAME "Instance name",
  341.    INSTANCE_NUMBER "Instance #",
  342.    THREAD# "Thread",
  343.    HOST_NAME "Hostname",
  344.    TO_CHAR(STARTUP_TIME,'Day, Month DD YYYY - HH24:MI:SS') "Startup time"
  345. FROM V$INSTANCE
  346. ";
  347.    $text = "Info about this instance.";
  348.    $link = "";
  349.    $infotext = "";
  350.    DisplayTable($sql,$text,$link,$infotext);
  351. # All instance info
  352. # The instance name wil be a hyperlink to connect to that database.
  353.    text("Info about all instances");
  354.    print <<"EOF";
  355. <TABLE BORDER=0 BGCOLOR='$bordercolor' CELLPADDING=1 CELLSPACING=0>
  356.   <TR>
  357.     <TD WIDTH=100%>
  358.       <TABLE BORDER=0 cellpadding=2 cellspacing=1>
  359.         <TH BGCOLOR='$headingcolor'><FONT COLOR='$headingfontcolor' SIZE='$fontsize' FACE='$headingfont'>Instance name</TH>
  360.         <TH BGCOLOR='$headingcolor'><FONT COLOR='$headingfontcolor' SIZE='$fontsize' FACE='$headingfont'>Instance number</TH>
  361.         <TH BGCOLOR='$headingcolor'><FONT COLOR='$headingfontcolor' SIZE='$fontsize' FACE='$headingfont'>Thread#</TH>
  362.         <TH BGCOLOR='$headingcolor'><FONT COLOR='$headingfontcolor' SIZE='$fontsize' FACE='$headingfont'>Hostname</TH>
  363.         <TH BGCOLOR='$headingcolor'><FONT COLOR='$headingfontcolor' SIZE='$fontsize' FACE='$headingfont'>Startup time</TH>
  364. EOF
  365.    $sql = "$copyright
  366. SELECT INSTANCE_NAME "Instance name",
  367.    INSTANCE_NUMBER "Instance #",
  368.    THREAD# "Thread",
  369.    HOST_NAME "Hostname",
  370.    TO_CHAR(STARTUP_TIME,'Day, Month DD YYYY - HH24:MI:SS') "Startup time"
  371. FROM GV$INSTANCE
  372.    ORDER BY INSTANCE_NAME
  373. ";
  374.    $cursor = $dbh->prepare($sql);
  375.    $cursor->execute;
  376.    while (($instance_name,$instance_number,$thread,$hostname,$startup_time) = $cursor->fetchrow_array) {
  377.       print "        <TR ALIGN=LEFT><TD VALIGN=TOP BGCOLOR='$cellcolor'><FONT COLOR='$fontcolor' SIZE='$fontsize' FACE='$font'><A href=$scriptname?database=$instance_name&object_type=FRAMEPAGE TARGET=_top>$instance_name</A></TD>n";
  378.       print <<"EOF";
  379.           <TD VALIGN=TOP BGCOLOR='$cellcolor'><FONT COLOR='$fontcolor' SIZE='$fontsize' FACE='$font'>$instance_number</A></TD>
  380.           <TD VALIGN=TOP BGCOLOR='$cellcolor'><FONT COLOR='$fontcolor' SIZE='$fontsize' FACE='$font'>$thread</A></TD>
  381.           <TD VALIGN=TOP BGCOLOR='$cellcolor'><FONT COLOR='$fontcolor' SIZE='$fontsize' FACE='$font'>$hostname</A></TD>
  382.           <TD VALIGN=TOP BGCOLOR='$cellcolor'><FONT COLOR='$fontcolor' SIZE='$fontsize' FACE='$font'>$startup_time</A></TD></TR>
  383. EOF
  384.    }
  385.    $cursor->finish;
  386.    print <<"EOF";
  387.       </TABLE>
  388.     </TD>
  389.   </TR>
  390. </TABLE>
  391. EOF
  392. # Locked objects
  393.    $sql = "$copyright
  394. SELECT
  395.    DO.OBJECT_NAME "Object name",
  396.    DO.OBJECT_TYPE "Object type",
  397.    DO.OWNER "Owner",
  398.    VLO.INST_ID "Instance ID",
  399.    VLO.SESSION_ID "SID",
  400.    VLO.ORACLE_USERNAME "Ora user",
  401.    VLO.OS_USER_NAME "OS user",
  402.    VLO.PROCESS "Process",
  403.    VLO.LOCKED_MODE "Mode"
  404. FROM GV$LOCKED_OBJECT VLO, DBA_OBJECTS DO
  405.    WHERE VLO.OBJECT_ID = DO.OBJECT_ID
  406. ";
  407.    $text = "Objects which currently have locks.";
  408.    $infotext = "There are currently no locked objects.";
  409.    ObjectTable($sql,$text,$infotext);
  410.    
  411. # Session list
  412.    $sql = "$copyright
  413. SELECT
  414.    GVS.INST_ID                                  "Instance",
  415.    GVS.USERNAME                                 "Ora user",
  416.    GVS.OSUSER                                   "OS user",
  417.    GVS.SID                                      "SID",
  418.    GVS.SERIAL#                                  "Serial#",
  419.    GVS.STATUS                                   "Status",
  420.    GVS.PROCESS                                  "Process",
  421.    GVS.PROGRAM                                  "Program",
  422.    TO_CHAR(GVS.LOGON_TIME,'Day MM/DD/YY HH24:MI')       "Logon time",
  423.    GVST.SQL_TEXT                                "SQL text"
  424. FROM GV$SESSION GVS, GV$SQLTEXT GVST
  425.    WHERE GVS.USERNAME IS NOT NULL
  426.    AND GVST.ADDRESS = GVS.SQL_ADDRESS
  427.    AND GVST.INST_ID = GVS.INST_ID
  428.    AND GVST.PIECE = 0
  429.    ORDER BY GVS.USERNAME, GVS.INST_ID, GVS.STATUS
  430. ";
  431.    $text = "Global session summary.";
  432.    $link = "";
  433.    $infotext = "";
  434.    DisplayTable($sql,$text,$link,$infotext);
  435. # Lock (IDLM) information
  436.    $sql = "$copyright
  437. SELECT
  438.    A.INSTANCE_NAME "Instance Name",
  439.    B.FROM_VAL "From",
  440.    B.TO_VAL "To",
  441.    B.ACTION_VAL "Action",
  442.    TO_CHAR(B.COUNTER,'999,999,999,999') "Counter"
  443. FROM GV$INSTANCE A, GV$LOCK_ACTIVITY B
  444.    WHERE B.INST_ID = A.INST_ID
  445.    ORDER BY A.INSTANCE_NAME, B.COUNTER DESC
  446. ";
  447.    $text = "Lock conversions by instance.";
  448.    $link = "";
  449.    $infotext = "No lock conversions";
  450.    DisplayTable($sql,$text,$link,$infotext);
  451.    logit("Exit subroutine OPSpage");
  452. }
  453.    
  454. sub showUsers {
  455.    logit("Enter subroutine showUsers");
  456.    my ($sql,$user,@dbausers,@connectedusers,$dba,$connected,$text,$cursor);
  457.    my (@lockedusers,$locked,$skip,$counter,$row,$usercount,$i);
  458.    my $highlight = "#FFFFC6";
  459.    my $redlight  = "#DEBDDE";
  460. # Show database connection info
  461.   logit("   Showing connection information"); 
  462.    print <<"EOF";
  463. Connected to database : $database<BR>
  464. $banner
  465. <P>
  466. EOF
  467.   logit("   Done showing connection information"); 
  468.   logit("   Getting list of users with DBA role"); 
  469. # Get all users who have the DBA role granted to them
  470.    $sql = "$copyright
  471. SELECT GRANTEE 
  472.    FROM DBA_ROLE_PRIVS
  473. WHERE GRANTED_ROLE='DBA'
  474. ";
  475.    $cursor = $dbh->prepare($sql) or ErrorPage ("$DBI::errstr");
  476.    $cursor->execute or ErrorPage ("$DBI::errstr");
  477.    while ($user = $cursor->fetchrow_array) { 
  478.       push (@dbausers,$user);
  479.    }
  480.    $cursor->finish;
  481.    logit("   Done getting list of users with DBA role"); 
  482. # Get all users whose account status is not "OPEN", if Oracle8
  483.    if ($oracle8) {
  484.       logit("   We are > oracle7: Getting users with non-open accounts");
  485.       $sql = "$copyright
  486. SELECT USERNAME
  487.    FROM DBA_USERS
  488. WHERE ACCOUNT_STATUS <> 'OPEN'
  489. ";
  490.       $cursor = $dbh->prepare($sql) or ErrorPage ("$DBI::errstr");
  491.       $cursor->execute or ErrorPage ("$DBI::errstr");
  492.       while ($user = $cursor->fetchrow_array) {
  493.          push (@lockedusers,$user);
  494.       }
  495.       $cursor->finish;
  496.       logit("   Done getting users with non-open accounts");
  497.    }
  498. # Get all users that are currently connected.
  499.    logit("   Getting list of currently connected users");
  500.    $sql = "$copyright
  501. SELECT DISTINCT USERNAME
  502.    FROM V$SESSION
  503. ";
  504.    $cursor = $dbh->prepare($sql) or ErrorPage ("$DBI::errstr");
  505.    $cursor->execute or ErrorPage ("$DBI::errstr");
  506.    while ($user = $cursor->fetchrow_array) {
  507.       push (@connectedusers,$user);
  508.    }
  509.    $cursor->finish;
  510.    logit("   Done getting list of currently connected users");
  511. # Display a count of all users.
  512.    logit("   Getting count of all users");
  513.    $sql = "$copyright
  514. SELECT COUNT(*)
  515.    FROM DBA_USERS
  516. ";
  517.    $cursor = $dbh->prepare($sql) or ErrorPage ("$DBI::errstr");
  518.    $cursor->execute or ErrorPage ("$DBI::errstr");
  519.    $usercount = $cursor->fetchrow_array;
  520.    $cursor->finish;
  521.    logit("   Done getting count of all users");
  522. # Get all usernames
  523.    $sql = "$copyright
  524. SELECT 
  525.    USERNAME 
  526. FROM DBA_USERS 
  527.    ORDER BY USERNAME
  528. ";
  529.    if ($oracle8) {
  530.       logit("   We are > Oracle7, so check for account status");
  531.       $text = "Select a schema by clicking on it.<BR>Yellow: User is connected. Red: Account locked / expired<BR>Bold text in parenthesis indicates DBA authority.";
  532.    } else {
  533.       logit("   We are < Oracle8, so don't check for account status");
  534.       $text = "Select a schema by clicking on it.<BR>Yellow background indicates user is connected.<BR>Bold text in parenthesis indicates DBA authority.";
  535.    }
  536.    $cursor = $dbh->prepare($sql) or ErrorPage ("$DBI::errstr");
  537.    $cursor->execute or ErrorPage ("$DBI::errstr");
  538.    $counter=0;
  539.    logit("   Generating HTML");
  540.    print "<B>$text</B><P>n";
  541.    print "<TABLE BORDER=0 BGCOLOR='$bordercolor' CELLPADDING=1 CELLSPACING=0>n";
  542.    print "  <TR>n";
  543.    print "    <TD WIDTH=100%>n";
  544.    print "      <TABLE BORDER=0 CELLPADDING=2 CELLSPACING=1>n";
  545.    print "        <TH COLSPAN=$schema_cols BGCOLOR='$headingcolor'><FONT COLOR='$headingfontcolor' SIZE='$fontsize' FACE='$headingfont'><B>Total # users: $usercount</B></TH>n"; 
  546.    while ($row = $cursor->fetchrow_array) {
  547.       undef $dba;
  548.       foreach $user (@dbausers) {
  549.          if ( $row eq $user ) {
  550.             $dba = "yes";
  551.             last;
  552.          }
  553.       }
  554.       undef $connected;
  555.       foreach $user (@connectedusers) {
  556.          if ( $row eq $user ) {
  557.             $connected = "yes";
  558.             last;
  559.          }
  560.       }
  561.       undef $locked;
  562.       foreach $user (@lockedusers) {
  563.          if ( $row eq $user ) {
  564.             $locked = "yes";
  565.             last;
  566.          }
  567.       }
  568.       print "<TR ALIGN=CENTER>" if $counter == 0;
  569.       if (($connected) && ($dba)) {
  570.          print "<TD BGCOLOR="$highlight"><FONT COLOR='$fontcolor' SIZE='$fontsize' FACE='$font'><STRONG><A href=$scriptname?database=$database&schema=$row&object_type=USERINFO>(${row})</A></STRONG></TD>n";
  571.       } elsif ($connected) {
  572.          print "<TD BGCOLOR="$highlight"><FONT COLOR='$fontcolor' SIZE='$fontsize' FACE='$font'><A href=$scriptname?database=$database&schema=$row&object_type=USERINFO>$row</A></TD>n";
  573.       } elsif ($locked) {
  574.          print "<TD BGCOLOR="$redlight"><FONT COLOR='$fontcolor' SIZE='$fontsize' FACE='$font'><A href=$scriptname?database=$database&schema=$row&object_type=USERINFO>$row</A></TD>n";
  575.       } elsif ($dba) {
  576.          print "<TD BGCOLOR='$cellcolor'><FONT COLOR='$fontcolor' SIZE='$fontsize' FACE='$font'><STRONG><A href=$scriptname?database=$database&schema=$row&object_type=USERINFO>(${row})</A></STRONG></TD>n";
  577.       } else {
  578.          print "<TD BGCOLOR='$cellcolor'><FONT COLOR='$fontcolor' SIZE='$fontsize' FACE='$font'><A href=$scriptname?database=$database&schema=$row&object_type=USERINFO>$row</A></TD>n";
  579.       }
  580.       $counter++;
  581.       print "</TR>" if $counter == 0;
  582.       $skip = "";
  583.       if ($counter == $schema_cols) { 
  584.          $counter = 0;
  585.          $skip = "Y";
  586.        }
  587.    }
  588.    if ((! $skip) && ($counter < $schema_cols)) {
  589.       for ($i = $counter; $i < $schema_cols; $i++) {
  590.          print "<TD BGCOLOR='$cellcolor'>&nbsp;</TD>n";
  591.       }
  592.    }
  593.    print "        </TR>n";
  594.    print "      </TABLE>n";
  595.    print "    </TD>n";
  596.    print "  </TR>n";
  597.    print "</TABLE>nn";
  598.    $cursor->finish or ErrorPage ("$DBI::errstr");
  599.    logit("Exit subroutine showUsers");
  600. sub showAuditTrail {
  601.    logit("Enter subroutine showAuditTrail");
  602.    my ($sql,$text,$link,$infotext,$command);
  603.    $command = $query->param('command');
  604.    logit("   Command: $command");
  605.    logit("   Object name: $object_name");
  606.    if ($command eq "statement") {
  607.       $sql = "$copyright
  608. SELECT
  609.    OS_USERNAME "OS user",
  610.    USERNAME "Username",
  611.    USERHOST "Host",
  612.    TERMINAL "Terminal",
  613.    TO_CHAR(TIMESTAMP,'Day, Month DD YYYY - HH24:MI:SS') "Timestamp",
  614.    OWNER "Owner",
  615.    OBJ_NAME "Object name",
  616.    ACTION_NAME "Action",
  617.    PRIV_USED "Priv used"
  618. FROM DBA_AUDIT_TRAIL
  619.    WHERE PRIV_USED = '$object_name'
  620.    ORDER BY TIMESTAMP DESC, OWNER
  621. ";
  622.    $text = "Audit records: $object_name.";
  623.    $link = "";
  624.    $infotext = "No audit records for $object_name.";
  625.    DisplayTable($sql,$text,$link,$infotext);
  626.    }
  627.    if ($command eq "object") {
  628.       $sql = "$copyright
  629. SELECT
  630.    OS_USERNAME "OS user",
  631.    USERNAME "Username",
  632.    USERHOST "Host",
  633.    TERMINAL "Terminal",
  634.    TO_CHAR(TIMESTAMP,'Day, Month DD YYYY - HH24:MI:SS') "Timestamp",
  635.    OWNER "Owner",
  636.    OBJ_NAME "Object name",
  637.    ACTION_NAME "Action",
  638.    PRIV_USED "Priv used"
  639. FROM DBA_AUDIT_TRAIL
  640.    WHERE OBJ_NAME = '$object_name'
  641.    ORDER BY TIMESTAMP DESC, OWNER
  642. ";
  643.    $text = "Audit records: $object_name.";
  644.    $link = "";
  645.    $infotext = "No audit records for $object_name.";
  646.    DisplayTable($sql,$text,$link,$infotext);
  647.    }
  648.    logit("Exit subroutine showAuditTrail");
  649. sub showAllAuditing {
  650.    logit("Enter subroutine showAllAuditing");
  651.    my ($sql,$text,$link,$infotext);
  652.    $sql = "$copyright
  653. SELECT 
  654.    AUDIT_OPTION "Audit option",
  655.    USER_NAME "Username",
  656.    SUCCESS "Success",
  657.    FAILURE "Failure"
  658. FROM DBA_STMT_AUDIT_OPTS
  659.    ORDER BY USER_NAME
  660. ";
  661.    $text        = "Statements / system privileges which are being audited.";
  662.    $link        = "$scriptname?database=$database&object_type=SHOWAUDITTRAIL&command=statement";
  663.    $infotext    = "No SQL statement / system privileges are being audited.";
  664.    DisplayTable($sql,$text,$link,$infotext); 
  665.    # Oracle7 SQL
  666.    $sql = "$copyright
  667. SELECT
  668.    OBJECT_NAME         "Object name",
  669.    OBJECT_TYPE         "Object type",
  670.    OWNER               "Owner",
  671.    ALT                 "Alter",
  672.    AUD                 "Audit",
  673.    COM                 "Comment",
  674.    DEL                 "Delete",
  675.    GRA                 "Grant",
  676.    IND                 "Index",
  677.    INS                 "Insert",
  678.    LOC                 "Lock",
  679.    REN                 "Rename",
  680.    SEL                 "Select",
  681.    UPD                 "Update",
  682.    REF                 "References",
  683.    EXE "Execute"
  684. FROM DBA_OBJ_AUDIT_OPTS
  685. WHERE ALT != '-/-'
  686. OR AUD != '-/-'
  687. OR COM != '-/-'
  688. OR DEL != '-/-'
  689. OR GRA != '-/-'
  690. OR IND != '-/-'
  691. OR INS != '-/-'
  692. OR LOC != '-/-'
  693. OR REN != '-/-'
  694. OR SEL != '-/-'
  695. OR UPD != '-/-'
  696. OR REF != '-/-'
  697. OR EXE != '-/-'
  698. ORDER BY OWNER
  699. ";
  700.    $sql = "$copyright
  701. SELECT
  702.    OBJECT_NAME         "Object name",
  703.    OBJECT_TYPE         "Object type",
  704.    OWNER               "Owner",
  705.    ALT                 "Alter",
  706.    AUD                 "Audit",
  707.    COM                 "Comment",
  708.    DEL                 "Delete",
  709.    GRA                 "Grant",
  710.    IND                 "Index",
  711.    INS                 "Insert",
  712.    LOC                 "Lock",
  713.    REN                 "Rename",
  714.    SEL                 "Select",
  715.    UPD                 "Update",
  716.    EXE                 "Execute",
  717.    CRE                 "Create",
  718.    REA                 "Read",
  719.    WRI                 "Write"
  720. FROM DBA_OBJ_AUDIT_OPTS
  721. WHERE ALT != '-/-'
  722. OR AUD != '-/-'
  723. OR COM != '-/-'
  724. OR DEL != '-/-'
  725. OR GRA != '-/-'
  726. OR IND != '-/-'
  727. OR INS != '-/-'
  728. OR LOC != '-/-'
  729. OR REN != '-/-'
  730. OR SEL != '-/-'
  731. OR UPD != '-/-'
  732. OR EXE != '-/-'
  733. OR CRE != '-/-'
  734. OR REA != '-/-'
  735. OR WRI != '-/-'
  736. ORDER BY OWNER
  737. " if ($oracle8);
  738.    $text        = "Auditing options pertaining to individual objects.";
  739.    $link        = "$scriptname?database=$database&object_type=SHOWAUDITTRAIL&command=object";
  740.    $infotext    = "No schema objects are being audited.";
  741.    DisplayTable($sql,$text,$link,$infotext); 
  742.    logit("Exit subroutine showAllAuditing");
  743. }
  744. sub Auditing {
  745.    logit("Enter subroutine Auditing");
  746.    my ($sql,$cursor,$value);
  747.    $sql = "$copyright
  748. SELECT
  749.    VALUE FROM V$PARAMETER
  750. WHERE NAME = 'audit_trail'
  751. ";
  752.    $cursor=$dbh->prepare($sql);
  753.    $cursor->execute;
  754.    $value = $cursor->fetchrow_array;
  755.    if ( (uc($value) ne "FALSE") && (uc($value) ne "NONE")) {
  756.       return(1);
  757.    } else {
  758.       return(0);
  759.    }
  760.    logit("Exit subroutine Auditing");
  761. }
  762. sub showSecurity {
  763.    logit("Enter subroutine showSecurity");
  764.    my ($sql,$cursor,$value,$text,$link,$infotext,$cols);
  765.    if ( Auditing() ) { 
  766.       print <<"EOF";
  767. <TABLE BORDER=0 CELLPADDING=0 CELLSPACING=0>
  768.   <TR>
  769.     <TD ALIGMN=CENTER>
  770.       <FORM METHOD="GET" ACTION="$scriptname">
  771.         <FONT COLOR='$fontcolor' SIZE='$fontsize' FACE='$font'>
  772.         <INPUT TYPE="HIDDEN" NAME="database" VALUE="$database">
  773.         <INPUT TYPE="HIDDEN" NAME="object_type" VALUE="AUDITING">
  774.         <INPUT TYPE="SUBMIT" NAME="auditing" VALUE="Auditing information">
  775.       </FORM>
  776.     </TD>
  777.   </TR>
  778. </TABLE>
  779. EOF
  780.     } else {
  781.       message("Database auditing is not enabled.");
  782.    } 
  783.    $sql = "$copyright
  784. SELECT 
  785.    ROLE
  786. FROM DBA_ROLES
  787.    ORDER BY ROLE
  788. ";
  789.    $text        = "All roles for this database";
  790.    $link = "$scriptname?database=$database&object_type=ROLES";
  791.    $infotext    = "There are no roles in this database";
  792.    DisplayColTable($sql,$text,$link,$infotext,$schema_cols); 
  793.    $sql = "$copyright
  794. SELECT DISTINCT
  795.    PROFILE
  796. FROM DBA_PROFILES
  797.    ORDER BY PROFILE
  798. ";
  799.    $text        = "All profiles for this database";
  800.    $link = "$scriptname?database=$database&object_type=PROFILE";
  801.    $infotext    = "There are no profiles in this database";
  802.    DisplayColTable($sql,$text,$link,$infotext,$schema_cols); 
  803.    $sql = "$copyright
  804. SELECT GRANTEE
  805.    FROM DBA_ROLE_PRIVS
  806. WHERE GRANTED_ROLE='DBA'
  807.    AND GRANTEE IN
  808. (SELECT USERNAME 
  809.    FROM DBA_USERS)
  810. "; 
  811.    $text        = "All users with the "DBA" role granted to them";
  812.    $link = "$scriptname?database=$database&object_type=USERINFO";
  813.    $infotext    = "There are no users with the "DBA" role in this database";
  814.    DisplayColTable($sql,$text,$link,$infotext,$schema_cols); 
  815.    $sql = "$copyright
  816. SELECT GRANTEE
  817.         FROM DBA_ROLE_PRIVS
  818. WHERE GRANTED_ROLE='DBA'
  819.    AND GRANTEE IN
  820. (SELECT ROLE
  821.    FROM DBA_ROLES)
  822. ";
  823.    $text        = "All roles with the "DBA" role granted to them";
  824.    $link        = "$scriptname?database=$database&object_type=ROLES";
  825.    $infotext    = "There are no roles with the "DBA" role in this database";
  826.    DisplayColTable($sql,$text,$link,$infotext,$schema_cols);
  827.    logit("Exit subroutine showSecurity");
  828. }
  829. sub showProfile {
  830.    logit("Enter subroutine showProfile");
  831.    my ($sql,$text,$link,$infotext);
  832.    $sql = "$copyright
  833. SELECT
  834.    RESOURCE_NAME        "Resource name",
  835.    LIMIT                "Limit"
  836. FROM DBA_PROFILES
  837.    WHERE PROFILE = '$object_name'
  838. ORDER BY RESOURCE_NAME
  839. " if ($oracle7);
  840.    $sql = "$copyright
  841. SELECT 
  842.    RESOURCE_NAME "Resource name",
  843.    RESOURCE_TYPE "Resource type",
  844.    LIMIT "Limit"
  845. FROM DBA_PROFILES
  846.    WHERE PROFILE = '$object_name'
  847. ORDER BY RESOURCE_NAME
  848. " if ($oracle8);
  849.    $text = "Profile $object_name";
  850.    $link = "";
  851.    $infotext = "";
  852.    DisplayTable($sql,$text,$link,$infotext); 
  853.    logit("Exit subroutine showProfile");
  854. }
  855. sub userInfo {
  856.    logit("Enter subroutine userInfo");
  857.    # User info
  858.    # Get the data from the database
  859.    my ($sql,$cursor,$count,$text,$link,$infotext,$cols);
  860.    my ($uname,$defts,$tmpts,$created,$profile,$objcount);
  861.    my ($status);
  862.    $schema = $object_name unless $schema;
  863. # General user info
  864.    $sql = "$copyright
  865. SELECT 
  866.    USERNAME,
  867.    DEFAULT_TABLESPACE,
  868.    TEMPORARY_TABLESPACE,
  869.    TO_CHAR(CREATED,'Month DD, YYYY - HH24:MI'),
  870.    PROFILE
  871. FROM DBA_USERS 
  872.    WHERE USERNAME = '$schema'
  873. ";
  874.    if ($oracle8) {
  875.       $sql = "$copyright
  876. SELECT
  877.    USERNAME,
  878.    DEFAULT_TABLESPACE,
  879.    TEMPORARY_TABLESPACE,
  880.    TO_CHAR(CREATED,'Month DD, YYYY - HH24:MI'),
  881.    PROFILE,
  882.    ACCOUNT_STATUS
  883. FROM DBA_USERS
  884.    WHERE USERNAME = '$schema'
  885. ";
  886.    }
  887.    $status = "";
  888.    $cursor=$dbh->prepare($sql);
  889.    $cursor->execute;
  890.    ($uname,$defts,$tmpts,$created,$profile,$status) = $cursor->fetchrow;
  891.    $cursor->finish;
  892.    if (! $oracle8) {
  893.       print <<"EOF";
  894. <TABLE BORDER=0 BGCOLOR='$bordercolor' CELLPADING=1 CELLSPACING=0>
  895.   <TR>
  896.     <TD WIDTH=100%>
  897.       <TABLE BORDER=0 CELLPADDING=2 CELLSPACING=1>
  898.         <TR>
  899.           <TH BGCOLOR='$headingcolor'><FONT COLOR='$headingfontcolor' SIZE='$fontsize' FACE='$headingfont'>User name</TH>
  900.           <TH BGCOLOR='$headingcolor'><FONT COLOR='$headingfontcolor' SIZE='$fontsize' FACE='$headingfont'>Default tablespace</TH>
  901.           <TH BGCOLOR='$headingcolor'><FONT COLOR='$headingfontcolor' SIZE='$fontsize' FACE='$headingfont'>Temp tablespace</TH>
  902.           <TH BGCOLOR='$headingcolor'><FONT COLOR='$headingfontcolor' SIZE='$fontsize' FACE='$headingfont'>User creation date</TH>
  903.           <TH BGCOLOR='$headingcolor'><FONT COLOR='$headingfontcolor' SIZE='$fontsize' FACE='$headingfont'>Profile</TH>
  904.         </TR>
  905.         <TR>
  906.           <TD BGCOLOR='$cellcolor'><FONT COLOR='$fontcolor' SIZE='$fontsize' FACE='$font'><A HREF=$scriptname?database=$database&object_type=USERDDL&schema=$schema>$uname</TD>
  907.           <TD BGCOLOR='$cellcolor'><FONT COLOR='$fontcolor' SIZE='$fontsize' FACE='$font'><A HREF=$scriptname?database=$database&object_type=TSINFO&schema=$schema&arg=$defts>$defts</TD>
  908.           <TD BGCOLOR='$cellcolor'><FONT COLOR='$fontcolor' SIZE='$fontsize' FACE='$font'><A HREF=$scriptname?database=$database&object_type=TSINFO&schema=$schema&arg=$tmpts>$tmpts</TD>
  909.           <TD BGCOLOR='$cellcolor'><FONT COLOR='$fontcolor' SIZE='$fontsize' FACE='$font'>$created</TD>
  910.           <TD BGCOLOR='$cellcolor'><FONT COLOR='$fontcolor' SIZE='$fontsize' FACE='$font'><A HREF=$scriptname?database=$database&object_type=PROFILE&arg=$profile>$profile</A></TD>
  911.         </TR>
  912.       </TABLE>
  913.     </TD>
  914.   </TR>
  915. </TABLE>
  916. EOF
  917.    } else {
  918.       print <<"EOF";
  919. <TABLE BORDER=0 BGCOLOR='$bordercolor' CELLPADING=1 CELLSPACING=0>
  920.   <TR>
  921.     <TD WIDTH=100%>
  922.       <TABLE BORDER=0 CELLPADDING=2 CELLSPACING=1>
  923.         <TR>
  924.           <TH BGCOLOR='$headingcolor'><FONT COLOR='$headingfontcolor' SIZE='$fontsize' FACE='$headingfont'>User name</TH>
  925.           <TH BGCOLOR='$headingcolor'><FONT COLOR='$headingfontcolor' SIZE='$fontsize' FACE='$headingfont'>Default tablespace</TH>
  926.           <TH BGCOLOR='$headingcolor'><FONT COLOR='$headingfontcolor' SIZE='$fontsize' FACE='$headingfont'>Temp tablespace</TH>
  927.           <TH BGCOLOR='$headingcolor'><FONT COLOR='$headingfontcolor' SIZE='$fontsize' FACE='$headingfont'>User creation date</TH>
  928.           <TH BGCOLOR='$headingcolor'><FONT COLOR='$headingfontcolor' SIZE='$fontsize' FACE='$headingfont'>Account status</TH>
  929.           <TH BGCOLOR='$headingcolor'><FONT COLOR='$headingfontcolor' SIZE='$fontsize' FACE='$headingfont'>Profile</TH>
  930.         </TR>
  931.         <TR>
  932.           <TD BGCOLOR='$cellcolor'><FONT COLOR='$fontcolor' SIZE='$fontsize' FACE='$font'><A HREF=$scriptname?database=$database&object_type=USERDDL&schema=$schema>$uname</TD>
  933.           <TD BGCOLOR='$cellcolor'><FONT COLOR='$fontcolor' SIZE='$fontsize' FACE='$font'><A HREF=$scriptname?database=$database&object_type=TSINFO&schema=$schema&arg=$defts>$defts</TD>
  934.           <TD BGCOLOR='$cellcolor'><FONT COLOR='$fontcolor' SIZE='$fontsize' FACE='$font'><A HREF=$scriptname?database=$database&object_type=TSINFO&schema=$schema&arg=$tmpts>$tmpts</TD>
  935.           <TD BGCOLOR='$cellcolor'><FONT COLOR='$fontcolor' SIZE='$fontsize' FACE='$font'>$created</TD>
  936.           <TD BGCOLOR='$cellcolor'><FONT COLOR='$fontcolor' SIZE='$fontsize' FACE='$font'>$status</TD>
  937.           <TD BGCOLOR='$cellcolor'><FONT COLOR='$fontcolor' SIZE='$fontsize' FACE='$font'><A HREF=$scriptname?database=$database&object_type=PROFILE&arg=$profile>$profile</A></TD>
  938.         </TR>
  939.       </TABLE>
  940.     </TD>
  941.   </TR>
  942. </TABLE>
  943. EOF
  944.    }
  945.     
  946. # Tablespace quotas
  947.    $sql = "$copyright
  948. SELECT 
  949.    TABLESPACE_NAME                       "Tablespace", 
  950.    TO_CHAR(BYTES,'999,999,999,999')      "Bytes used", 
  951. DECODE 
  952. (
  953.    MAX_BYTES,
  954.       '-1','Unlimited', TO_CHAR(MAX_BYTES,'999,999,999,999')
  955. )                                        "Quota"  
  956. FROM DBA_TS_QUOTAS 
  957.    WHERE USERNAME = '$schema'
  958. ";
  959.    $text = "Tablespace quotas";
  960.    $link = "$scriptname?database=$database&object_type=TSINFO&schema=$schema";
  961.    $infotext = "$schema has no individual tablespace quotas.";
  962.    DisplayTable($sql,$text,$link,$infotext);
  963. # Buttons for displaying grants / session info
  964. print <<"EOF";
  965. <P>
  966. <TABLE BORDER=0>
  967.   <TR ALIGN=CENTER>
  968.     <TD>
  969.       <FORM METHOD="GET" ACTION="$scriptname">
  970.         <FONT COLOR='$fontcolor' SIZE='$fontsize' FACE='$font'>
  971.         <INPUT TYPE="HIDDEN" NAME="database" VALUE="$database">
  972.         <INPUT TYPE="HIDDEN" NAME="schema" VALUE="$schema">
  973.         <INPUT TYPE="HIDDEN" NAME="object_type" VALUE="GRANTSTO">
  974.         <INPUT TYPE="SUBMIT" NAME="togrants" VALUE="Display grants to $schema">
  975.       </FORM>
  976.     </TD>
  977.     <TD>
  978.       <FORM METHOD="GET" ACTION="$scriptname">
  979.         <FONT COLOR='$fontcolor' SIZE='$fontsize' FACE='$font'>
  980.         <INPUT TYPE="HIDDEN" NAME="database" VALUE="$database">
  981.         <INPUT TYPE="HIDDEN" NAME="schema" VALUE="$schema">
  982.         <INPUT TYPE="HIDDEN" NAME="object_type" VALUE="GRANTSFROM">
  983.         <INPUT TYPE="SUBMIT" NAME="fromgrants" VALUE="Display grants from $schema">
  984.       </FORM>
  985.     </TD>
  986.   </TR>
  987. EOF
  988. # Display a button if the user currently has sessions in this instance.
  989.    $sql = "$copyright
  990. SELECT COUNT(*) 
  991.    FROM V$SESSION 
  992. WHERE USERNAME = '$schema'
  993. ";
  994.    $cursor=$dbh->prepare($sql);
  995.    $cursor->execute;
  996.    $count = $cursor->fetchrow_array;
  997.    $cursor->finish;
  998.    if ($count > 0) {
  999. print <<"EOF";
  1000.   <TR>
  1001.     <TD COLSPAN=2 ALIGN=CENTER>
  1002.       <FORM METHOD="GET" ACTION="$scriptname">
  1003.         <FONT COLOR='$fontcolor' SIZE='$fontsize' FACE='$font'>
  1004.         <INPUT TYPE="HIDDEN" NAME="database" VALUE="$database">
  1005.         <INPUT TYPE="HIDDEN" NAME="user" VALUE="$schema">
  1006.         <INPUT TYPE="HIDDEN" NAME="object_type" VALUE="SESSIONS">
  1007.         <INPUT TYPE="SUBMIT" NAME="sessions" VALUE="Display $schema session info">
  1008.       </FORM>
  1009.     </TD>
  1010.   </TR>
  1011. </TABLE>
  1012. EOF
  1013.    } else {
  1014. print <<"EOF";
  1015. </TABLE>
  1016. EOF
  1017.    message("$schema has no sessions in this instance.");
  1018.    }
  1019. # Check to see if there are any public synonyms pointing
  1020. # to objects owned by the schema selected.
  1021.    $sql = "$copyright
  1022. SELECT 
  1023.    COUNT(*) 
  1024. FROM DBA_SYNONYMS
  1025.    WHERE TABLE_OWNER = '$schema'
  1026.    AND OWNER = 'PUBLIC'
  1027. ";
  1028.    $cursor = $dbh->prepare($sql);
  1029.    $cursor->execute;
  1030.    $objcount = $cursor->fetchrow_array || "";
  1031.    $cursor->finish;
  1032. # Get object types owned by user
  1033.    if ($objcount) {
  1034.       $sql = "$copyright
  1035. SELECT DISTINCT 
  1036.    OBJECT_TYPE "Object type" 
  1037. FROM DBA_OBJECTS 
  1038.    WHERE OWNER = '$schema'
  1039.    AND OBJECT_TYPE != 'UNDEFINED'
  1040. UNION
  1041.    SELECT
  1042. DECODE(DUMMY,'X','PUBLIC SYNONYMS')
  1043.    FROM DUAL
  1044. ";
  1045.       $text = "Object types owned by $schema, + public synonyms.<BR>Click an object type for a list.";
  1046.    } else {
  1047.     
  1048.       $sql = "$copyright
  1049. SELECT DISTINCT
  1050.    OBJECT_TYPE                          "Object type"
  1051. FROM DBA_OBJECTS
  1052.    WHERE OWNER = '$schema'
  1053.    AND OBJECT_TYPE != 'UNDEFINED'
  1054. ";
  1055.       $text = "Object types owned by $schema.<BR>Click an object type for a list.";
  1056.    }
  1057.    $link = "$scriptname?database=$database&schema=$schema&object_type=LISTOBJECTS";
  1058.    $infotext = "There are no objects owned by $schema in this database.";
  1059.    DisplayColTable($sql,$text,$link,$infotext,$schema_cols);
  1060.    $sql = "$copyright
  1061. SELECT COUNT(*) FROM DBA_OBJECTS WHERE OWNER = '$schema'
  1062. ";
  1063.    $cursor = $dbh->prepare($sql);
  1064.    $cursor->execute;
  1065.    $objcount = $cursor->fetchrow_array;
  1066.    $cursor->finish;
  1067.    if ($objcount) {
  1068.       $sql = "$copyright
  1069. SELECT
  1070.    COUNT(DECODE(TYPE, 2, OBJ#, '')) "Table",
  1071.    COUNT(DECODE(TYPE, 1, OBJ#, '')) "Index",
  1072.    COUNT(DECODE(TYPE, 5, OBJ#, '')) "Synonym",
  1073.    COUNT(DECODE(TYPE, 4, OBJ#, '')) "View`",
  1074.    COUNT(DECODE(TYPE, 6, OBJ#, '')) "Sequence",
  1075.    COUNT(DECODE(TYPE, 7, OBJ#, '')) "Procedure",
  1076.    COUNT(DECODE(TYPE, 8, OBJ#, '')) "Function",
  1077.    COUNT(DECODE(TYPE, 9, OBJ#, '')) "Package",
  1078.    COUNT(DECODE(TYPE,12, OBJ#, '')) "Trigger",
  1079.    COUNT(DECODE(TYPE,10, OBJ#, '')) "Dependency"
  1080. FROM SYS.OBJ$
  1081.    WHERE OWNER# = 
  1082. (
  1083. SELECT USER_ID 
  1084.    FROM DBA_USERS 
  1085. WHERE USERNAME = '$schema'
  1086. )
  1087. " if $oracle7;
  1088.       $sql = "$copyright
  1089. SELECT
  1090.    COUNT(DECODE(TYPE#, 2, OBJ#, '')) "Table",
  1091.    COUNT(DECODE(TYPE#, 1, OBJ#, '')) "Index",
  1092.    COUNT(DECODE(TYPE#, 5, OBJ#, '')) "Synonym",
  1093.    COUNT(DECODE(TYPE#, 4, OBJ#, '')) "View",
  1094.    COUNT(DECODE(TYPE#, 6, OBJ#, '')) "Sequence",
  1095.    COUNT(DECODE(TYPE#, 7, OBJ#, '')) "Procedure",
  1096.    COUNT(DECODE(TYPE#, 8, OBJ#, '')) "Function",
  1097.    COUNT(DECODE(TYPE#, 9, OBJ#, '')) "Package",
  1098.    COUNT(DECODE(TYPE#,12, OBJ#, '')) "Trigger",
  1099.    COUNT(DECODE(TYPE#,10, OBJ#, '')) "Dependency"
  1100. FROM SYS.OBJ$
  1101.    WHERE OWNER# = 
  1102. (
  1103. SELECT USER_ID 
  1104.    FROM DBA_USERS 
  1105. WHERE USERNAME = '$schema'
  1106. )
  1107. " if $oracle8;
  1108.       $text = "Object count";
  1109.       $link = "";
  1110.       DisplayTable($sql,$text,$link);
  1111.    }
  1112.    $sql = "$copyright
  1113. SELECT 
  1114.    COUNT(*)
  1115. FROM DBA_OBJECTS
  1116.    WHERE OWNER = '$schema'
  1117. AND OBJECT_TYPE IN ('TABLE','INDEX','CLUSTER')
  1118. ";
  1119.    $cursor=$dbh->prepare($sql);
  1120.    $cursor->execute;
  1121.    $count = $cursor->fetchrow_array;
  1122.    if ($count > 0) {
  1123.       print <<"EOF";
  1124. </FONT>
  1125. <FORM METHOD="GET" ACTION="$scriptname">
  1126.   <FONT COLOR='$fontcolor' SIZE='$fontsize' FACE='$font'>
  1127.   <INPUT TYPE="HIDDEN" NAME="database" VALUE="$database">
  1128.   <INPUT TYPE="HIDDEN" NAME="schema" VALUE="$schema">
  1129.   <INPUT TYPE="HIDDEN" NAME="object_type" VALUE="OBJECTREPORT">
  1130.   <INPUT TYPE="SUBMIT" NAME="objectreport" VALUE="Object report by tablespace.">
  1131. </FORM>
  1132. EOF
  1133.    }
  1134.    if ($objcount) {
  1135.       $sql = "$copyright
  1136. SELECT COUNT(*)
  1137.    FROM DBA_OBJECTS
  1138. WHERE OWNER = '$schema'
  1139. AND STATUS = 'INVALID'
  1140. ";
  1141.       $cursor = $dbh->prepare($sql);
  1142.       $cursor->execute;
  1143.       $count = $cursor->fetchrow_array;
  1144.       $cursor->finish;
  1145.       if ($count > 0) {
  1146.          if (checkPriv("ALTER ANY PROCEDURE")) {
  1147.             print <<"EOF";
  1148. </FONT>
  1149. <FORM METHOD="GET" ACTION="$scriptname">
  1150.   <FONT COLOR='$fontcolor' SIZE='$fontsize' FACE='$font'>
  1151.   <INPUT TYPE="HIDDEN" NAME="database" VALUE="$database">
  1152.   <INPUT TYPE="HIDDEN" NAME="schema" VALUE="$schema">
  1153.   <INPUT TYPE="HIDDEN" NAME="object_type" VALUE="SHOWINVALIDOBJECTS">
  1154.   <INPUT TYPE="SUBMIT" NAME="objectreport" VALUE="Display $count invalid objects.">
  1155. </FORM>
  1156. EOF
  1157.          } else {
  1158.             message("There are $count invalid objects in this schema.n");
  1159.          }
  1160.       } else {
  1161.          message("There are no invalid objects in this schema.n");
  1162.       }
  1163.    }
  1164.    logit("Exit subroutine userInfo");
  1165. }
  1166. sub showInvalidObjects {
  1167.    invalidObjectList($schema);
  1168. }
  1169. sub enterExtentReport {
  1170.    logit("Enter subroutine enterExtentReport");
  1171.    text("Enter a value below. A report will be generated showing all objects with a number of extents greater than or equal to the number you have entered. (Objects with unusually large number of extents)");
  1172.    print <<"EOF";
  1173.       <FORM METHOD="GET" ACTION="$scriptname">
  1174.         <FONT COLOR='$fontcolor' SIZE='$fontsize' FACE='$font'>
  1175.         <INPUT TYPE="HIDDEN" NAME="database" VALUE="$database">
  1176.         <INPUT TYPE="HIDDEN" NAME="object_type" VALUE="EXTENTREPORT">
  1177.         <INPUT TYPE=TEXT MAXLENGTH=10 SIZE=10 NAME=extents1 VALUE=1000>
  1178. EOF
  1179.    text("Enter a value below. A report will be generated showing all objects with a number of extents greater than MAX_EXTENTS minus this number. (Objects nearing max extents)");
  1180.    print "     <INPUT TYPE=TEXT MAXLENGTH=10 SIZE=10 NAME=extents2 VALUE=25><P>n";
  1181.    print <<"EOF";
  1182.         <INPUT TYPE="SUBMIT" NAME="foo" VALUE="Generate report">
  1183.       </FORM>
  1184. EOF
  1185.    logit("Exit subroutine enterExtentReport");
  1186. }
  1187. sub extentReport {
  1188.    logit("Enter subroutine extentReport");
  1189.    my ($sql,$cursor,$tablespace_name,$link,$text,$infotext,$extents1,$extents2);
  1190.    my (@tablespaces);
  1191.    $extents1 = $query->param('extents1');
  1192.    $extents2 = $query->param('extents2');
  1193.    logit("   Looking for objects with extents > $extents1");
  1194.    $sql = "$copyright
  1195. SELECT
  1196.    SEGMENT_NAME                                 "Object name",
  1197.    SEGMENT_TYPE                                 "Object type",
  1198.    OWNER                                        "Owner",
  1199.    TO_CHAR(COUNT(*),'999,999,999,999') "Extents",
  1200.    TO_CHAR(SUM(BYTES),'999,999,999,999') "Bytes",
  1201.    TABLESPACE_NAME                              "Tablespace name"
  1202. FROM DBA_EXTENTS
  1203.    GROUP BY SEGMENT_TYPE, SEGMENT_NAME, TABLESPACE_NAME, OWNER
  1204.    HAVING COUNT(*) >= $extents1 
  1205.    ORDER BY 4 DESC
  1206. ";
  1207.    $text = "Objects with a number of extents >= $extents1.";
  1208.    $infotext = "There are no objects with extents >= $extents1.";
  1209.    ObjectTable($sql,$text,$infotext);
  1210.    logit("   SQL = n$sql");
  1211.    logit("   Error: $DBI::errstr") if $DBI::errstr;
  1212.    print "<HR WIDTH='75%'>n";
  1213.       $sql = "$copyright
  1214. SELECT
  1215.    SEGMENT_NAME                                 "Object name",
  1216.    SEGMENT_TYPE                                 "Object type",
  1217.    OWNER                                        "Owner",
  1218.    TABLESPACE_NAME                              "Tablespace name",
  1219.    TO_CHAR(EXTENTS,'999,999,999,999')           "Extents",
  1220.    TO_CHAR(MAX_EXTENTS,'999,999,999,999')       "Max extents"
  1221. FROM DBA_SEGMENTS
  1222.    WHERE EXTENTS > (MAX_EXTENTS-$extents2)
  1223.    AND SEGMENT_TYPE != 'CACHE'
  1224. ";
  1225.    $text = "Objects that are approaching their max_extents limit.";
  1226.    $infotext = "No objects in the database have extents > ( max_extents - $extents2 ).";
  1227.    ObjectTable($sql,$text,$infotext);
  1228.    print "<HR WIDTH='75%'>n";
  1229.    text("Checking all tablespaces for objects which cannot allocate a next extent due to lack of space.");
  1230.    $sql = "$copyright
  1231. SELECT 
  1232.    TABLESPACE_NAME 
  1233. FROM DBA_TABLESPACES
  1234.    ORDER BY TABLESPACE_NAME
  1235. ";
  1236.    $cursor = $dbh->prepare($sql);
  1237.    $cursor->execute;
  1238.    while ($tablespace_name = $cursor->fetchrow_array) {
  1239.       push @tablespaces, $tablespace_name;
  1240.    }
  1241.    $cursor->finish;
  1242.    foreach $tablespace_name(@tablespaces) {
  1243.       $sql = "$copyright
  1244. SELECT
  1245.    SEGMENT_NAME                                 "Object name",
  1246.    SEGMENT_TYPE                                 "Object type",
  1247.    OWNER                                        "Owner",
  1248.    TO_CHAR(NEXT_EXTENT,'999,999,999,999')       "Next extent"
  1249. FROM DBA_SEGMENTS
  1250.    WHERE TABLESPACE_NAME = '$tablespace_name'
  1251.    AND NEXT_EXTENT > (SELECT NVL(MAX(BYTES),'0') FROM DBA_FREE_SPACE
  1252. WHERE TABLESPACE_NAME = '$tablespace_name')
  1253. ";
  1254.       $text = "Objects in tablespace $tablespace_name which cannot allocate a next extent.";
  1255.       $link = "";
  1256.       $infotext = "Tablespace $tablespace_name OK.";
  1257.       ObjectTable($sql,$text,$infotext);
  1258.    }
  1259.    text("Done.");
  1260.    logit("Exit subroutine extentReport");
  1261. }
  1262. sub userSpaceReport {
  1263.    logit("Enter subroutine userSpaceReport");
  1264.    my ($sql,$link,$text,$sortfield,$owner,$bytes,$highlight,$color,$count);
  1265.    $sortfield = $query->param('sortfield') || "3";
  1266.    $highlight = "#FFFFC6";
  1267.    text("Click on a column name to change sort order.");
  1268.    print << "EOF";
  1269. <TABLE BORDER =0 BGCOLOR='$bordercolor' CELLPADDING=1 CELLSPACING=0>
  1270.   <TR>
  1271.     <TD WIDTH=100%>
  1272.       <TABLE BORDER=0 CELLPADDING=2 CELLSPACING=1>
  1273. EOF
  1274.    if ($sortfield eq "1") {
  1275.       $color = $highlight;
  1276.    } else {
  1277.       $color = $headingcolor;
  1278.    }
  1279.    print "         <TH BGCOLOR='$color' ALIGN=LEFT><FONT COLOR='$headingfontcolor' SIZE='$fontsize' FACE='$headingfont'><A HREF=$scriptname?database=$database&object_type=$object_type&arg=$object_name&sortfield=1>Owner</A></TH>n";
  1280.    if ($sortfield eq "2") {
  1281.       $sortfield = "2 DESC";
  1282.       $color = $highlight;
  1283.    } else {
  1284.       $color = $headingcolor;
  1285.    }
  1286.    print "         <TH BGCOLOR='$color' ALIGN=LEFT><FONT COLOR='$headingfontcolor' SIZE='$fontsize' FACE='$headingfont'><A HREF=$scriptname?database=$database&object_type=$object_type&arg=$object_name&sortfield=2>Object count</A></TH>n";
  1287.    if ($sortfield eq "3") {
  1288.       $sortfield = "3 DESC";
  1289.       $color = $highlight;
  1290.    } else {
  1291.       $color = $headingcolor;
  1292.    }
  1293.    print "         <TH BGCOLOR='$color' ALIGN=LEFT><FONT COLOR='$headingfontcolor' SIZE='$fontsize' FACE='$headingfont'><A HREF=$scriptname?database=$database&object_type=$object_type&arg=$object_name&sortfield=3>Bytes</A></TH>n";
  1294.    $sql = "$copyright
  1295. SELECT
  1296.    OWNER,
  1297.    TO_CHAR(COUNT(*),'999,999,999,999'),
  1298.    TO_CHAR(SUM(BYTES),'999,999,999,999')
  1299. FROM DBA_SEGMENTS
  1300.    GROUP BY OWNER
  1301.    ORDER by $sortfield
  1302. ";
  1303.    $cursor = $dbh->prepare($sql);
  1304.    $cursor->execute;
  1305.    while (($owner,$count,$bytes) = $cursor->fetchrow_array) {
  1306.       print "<TR><TD BGCOLOR='$cellcolor'><FONT COLOR='$fontcolor' SIZE='$fontsize' FACE='$font'><A HREF=$scriptname?database=$database&object_type=OBJECTREPORT&arg=$owner>$owner</A></TD>n";
  1307.       print "<TD BGCOLOR='$cellcolor'><FONT COLOR='$fontcolor' SIZE='$fontsize' FACE='$font'>$count</TD>n";
  1308.       print "<TD BGCOLOR='$cellcolor'><FONT COLOR='$fontcolor' SIZE='$fontsize' FACE='$font'>$bytes</TD></TR>n";
  1309.    }
  1310.    $cursor->finish;
  1311.    print <<"EOF";
  1312.       </TABLE>
  1313.     </TD>
  1314.   </TR>
  1315. </TABLE>
  1316. EOF
  1317.    logit("Exit subroutine userSpaceReport");
  1318. }
  1319. sub fileFragReport {
  1320.    logit("Enter subroutine fileFragReport");
  1321.    my ($sql,$link,$text,$sortfield,$file_name,$bytes,$largest,$smallest,$frags);
  1322.    my ($highlight,$color,$count,$tablespace_name,@needs_coalescing);
  1323.    my $maxfrags = 1000;
  1324.    $sortfield = $query->param('sortfield') || "4";
  1325.    $highlight = "#FFFFC6";
  1326.    text("Click on a column name to change sort order.");
  1327.    print << "EOF";
  1328. <TABLE BORDER =0 BGCOLOR='$bordercolor' CELLPADDING=1 CELLSPACING=0>
  1329.   <TR>
  1330.     <TD WIDTH=100%>
  1331.       <TABLE BORDER=0 CELLPADDING=2 CELLSPACING=1>
  1332. EOF
  1333.    if ($sortfield eq "1") {
  1334.       $color = $highlight;
  1335.    } else {
  1336.       $color = $headingcolor;
  1337.    }
  1338.    print "         <TH BGCOLOR='$color' ALIGN=LEFT><FONT COLOR='$headingfontcolor' SIZE='$fontsize' FACE='$headingfont'><A HREF=$scriptname?database=$database&object_type=$object_type&arg=$object_name&sortfield=1>File name</A></TH>n";
  1339.    if ($sortfield eq "2") {
  1340.       $sortfield = "2 DESC";
  1341.       $color = $highlight;
  1342.    } else {
  1343.       $color = $headingcolor;
  1344.    }
  1345.    print "         <TH BGCOLOR='$color' ALIGN=LEFT><FONT COLOR='$headingfontcolor' SIZE='$fontsize' FACE='$headingfont'><A HREF=$scriptname?database=$database&object_type=$object_type&arg=$object_name&sortfield=2>Bytes</A></TH>n";
  1346.    if ($sortfield eq "3") {
  1347.       $color = $highlight;
  1348.    } else {
  1349.       $color = $headingcolor;
  1350.    }
  1351.    print "         <TH BGCOLOR='$color' ALIGN=LEFT><FONT COLOR='$headingfontcolor' SIZE='$fontsize' FACE='$headingfont'><A HREF=$scriptname?database=$database&object_type=$object_type&arg=$object_name&sortfield=3>Tablespace name</A></TH>n";
  1352.    if ($sortfield eq "4") {
  1353.       $sortfield = "4 DESC";
  1354.       $color = $highlight;
  1355.    } else {
  1356.       $color = $headingcolor;
  1357.    }
  1358.    print "         <TH BGCOLOR='$color' ALIGN=LEFT><FONT COLOR='$headingfontcolor' SIZE='$fontsize' FACE='$headingfont'><A HREF=$scriptname?database=$database&object_type=$object_type&arg=$object_name&sortfield=4>Fragments</A></TH>n";
  1359.    if ($sortfield eq "5") {
  1360.       $sortfield = "5 DESC";
  1361.       $color = $highlight;
  1362.    } else {
  1363.       $color = $headingcolor;
  1364.    }
  1365.    print "         <TH BGCOLOR='$color' ALIGN=LEFT><FONT COLOR='$headingfontcolor' SIZE='$fontsize' FACE='$headingfont'><A HREF=$scriptname?database=$database&object_type=$object_type&arg=$object_name&sortfield=5>Largest free chunk</A></TH>n";
  1366.    if ($sortfield eq "6") {
  1367.       $color = $highlight;
  1368.    } else {
  1369.       $color = $headingcolor;
  1370.    }
  1371.    print "         <TH BGCOLOR='$color' ALIGN=LEFT><FONT COLOR='$headingfontcolor' SIZE='$fontsize' FACE='$headingfont'><A HREF=$scriptname?database=$database&object_type=$object_type&arg=$object_name&sortfield=6>Smallest free chunk</A></TH>n";
  1372. $sql = "$copyright
  1373. SELECT 
  1374.    A.FILE_NAME "File name",
  1375.    TO_CHAR(A.BYTES,'999,999,999,999') "Bytes",
  1376.    A.TABLESPACE_NAME "Tablespace name",
  1377.    COUNT(*) "Pieces",
  1378.    TO_CHAR(NVL(MAX(B.BYTES),'0'),'999,999,999,999') "Largest free chunk", 
  1379.    TO_CHAR(NVL(MIN(B.BYTES),'0'),'999,999,999,999') "Smallest free chunk"
  1380. FROM DBA_DATA_FILES A, DBA_FREE_SPACE B
  1381. WHERE A.FILE_ID = B.FILE_ID(+)
  1382. GROUP BY A.FILE_NAME, A.BYTES, A.TABLESPACE_NAME
  1383. ORDER BY $sortfield
  1384. ";
  1385.    logit("   SQL = $sql");
  1386.    $cursor = $dbh->prepare($sql);
  1387.    logit("   Error: $DBI::errstr") if $DBI::errstr;
  1388.    $cursor->execute;
  1389.    while (($file_name,$bytes,$tablespace_name,$frags,$largest,$smallest) = $cursor->fetchrow_array) {
  1390. # Push tablespace_name into an array if the tablespace needs coalescing.
  1391.       if ($frags >= $maxfrags) {
  1392.          push @needs_coalescing, "'$file_name'";
  1393.          logit("   File $file_name needs coalescing.");
  1394.       }
  1395.       print "<TR><TD BGCOLOR='$cellcolor'><FONT COLOR='$fontcolor' SIZE='$fontsize' FACE='$font'><A HREF=$scriptname?database=$database&object_type=DATAFILE&arg=$file_name>$file_name</A></TD>n";
  1396.       print "<TD BGCOLOR='$cellcolor'><FONT COLOR='$fontcolor' SIZE='$fontsize' FACE='$font'>$bytes</TD>n";
  1397.       print "<TD BGCOLOR='$cellcolor'><FONT COLOR='$fontcolor' SIZE='$fontsize' FACE='$font'><A HREF=$scriptname?database=$database&object_type=TSINFO&arg=$tablespace_name>$tablespace_name</A></TD>n";
  1398.       print "<TD BGCOLOR='$cellcolor'><FONT COLOR='$fontcolor' SIZE='$fontsize' FACE='$font'>$frags</TD>n";
  1399.       print "<TD BGCOLOR='$cellcolor'><FONT COLOR='$fontcolor' SIZE='$fontsize' FACE='$font'>$largest</TD>n";
  1400.       print "<TD BGCOLOR='$cellcolor'><FONT COLOR='$fontcolor' SIZE='$fontsize' FACE='$font'>$smallest</TD></TR>n";
  1401.    }
  1402.    $cursor->finish;
  1403.    print <<"EOF";
  1404.       </TABLE>
  1405.     </TD>
  1406.   </TR>
  1407. </TABLE>
  1408. EOF
  1409.    # Print a list of "ALTER TABLESAPCE tablespace name COALESCE statements
  1410.    if (@needs_coalescing) {
  1411.       my $file_names = join(",",@needs_coalescing);
  1412.       logit("   Files to be coalesced: $file_names");
  1413.       text("Coalesce statements for tablespaces containing datafiles which have at least $maxfrags fragments.");
  1414.       print <<"EOF";
  1415. <TABLE BORDER=0 BGCOLOR='$bordercolor' CELLPADDING=1 CELLSPACING=0>
  1416.   <TR>
  1417.     <TD WIDTH=100%>
  1418.       <TABLE BORDER=0 CELLPADDING=2 CELLSPACING=1>
  1419.         <TR>
  1420.           <TD BGCOLOR='$cellcolor'>
  1421.             <PRE>
  1422. /* 
  1423.    Database $database
  1424.    DDL generated by Oracletool v$VERSION
  1425.    for any tablespace containing at least
  1426.    one datafile with more than $maxfrags 
  1427.    fragments.
  1428. */
  1429. EOF
  1430.        $sql = "$copyright
  1431. SELECT DISTINCT TABLESPACE_NAME
  1432.    FROM DBA_DATA_FILES
  1433. WHERE FILE_NAME IN ($file_names)
  1434. ";
  1435.       $cursor = $dbh->prepare($sql) or print("$DBI::errstrn");
  1436.       $cursor->execute;
  1437.       while ($tablespace_name = $cursor->fetchrow_array) {
  1438.          logit("   Writing statement for tablespace $tablespace_name");
  1439.          print "ALTER TABLESPACE $tablespace_name COALESCE;n"
  1440.       }
  1441.       $cursor->finish;
  1442.       print <<"EOF";
  1443.           </TD>
  1444.         </TR>
  1445.       </TABLE>
  1446.     </TD>
  1447.   </TR>
  1448. </TABLE>
  1449. EOF
  1450.    }
  1451.    logit("Exit subroutine fileFragReport");
  1452. }
  1453. sub tsSpaceReport {
  1454.    logit("Enter subroutine tsSpaceReport");
  1455.    my ($sql,$link,$text,$sortfield,$owner,$tablespace_name,$bytes);
  1456.    my ($highlight,$color,$count);
  1457.    $sortfield = $query->param('sortfield') || "4";
  1458.    $highlight = "#FFFFC6";
  1459.    text("Click on a column name to change sort order.");
  1460.    print << "EOF";
  1461. <TABLE BORDER =0 BGCOLOR='$bordercolor' CELLPADDING=1 CELLSPACING=0>
  1462.   <TR>
  1463.     <TD WIDTH=100%>
  1464.       <TABLE BORDER=0 CELLPADDING=2 CELLSPACING=1>
  1465. EOF
  1466.    if ($sortfield eq "1") {
  1467.       $color = $highlight;
  1468.    } else {
  1469.       $color = $headingcolor;
  1470.    }
  1471.    print "         <TH BGCOLOR='$color' ALIGN=LEFT><FONT COLOR='$headingfontcolor' SIZE='$fontsize' FACE='$headingfont'><A HREF=$scriptname?database=$database&object_type=$object_type&arg=$object_name&sortfield=1>Owner</A></TH>n";
  1472.    if ($sortfield eq "2") {
  1473.       $color = $highlight;
  1474.    } else {
  1475.       $color = $headingcolor;
  1476.    }
  1477.    print "         <TH BGCOLOR='$color' ALIGN=LEFT><FONT COLOR='$headingfontcolor' SIZE='$fontsize' FACE='$headingfont'><A HREF=$scriptname?database=$database&object_type=$object_type&arg=$object_name&sortfield=2>Tablespace name</A></TH>n";
  1478.    if ($sortfield eq "3") {
  1479.       $sortfield = "3 DESC";
  1480.       $color = $highlight;
  1481.    } else {
  1482.       $color = $headingcolor;
  1483.    }
  1484.    print "         <TH BGCOLOR='$color' ALIGN=LEFT><FONT COLOR='$headingfontcolor' SIZE='$fontsize' FACE='$headingfont'><A HREF=$scriptname?database=$database&object_type=$object_type&arg=$object_name&sortfield=3>Object count</A></TH>n";
  1485.    if ($sortfield eq "4") {
  1486.       $sortfield = "4 DESC";
  1487.       $color = $highlight;
  1488.    } else {
  1489.       $color = $headingcolor;
  1490.    }
  1491.    print "         <TH BGCOLOR='$color' ALIGN=LEFT><FONT COLOR='$headingfontcolor' SIZE='$fontsize' FACE='$headingfont'><A HREF=$scriptname?database=$database&object_type=$object_type&arg=$object_name&sortfield=4>Bytes used</A></TH>n";
  1492.    $sql = "$copyright
  1493. SELECT
  1494.    OWNER,
  1495.    TABLESPACE_NAME,
  1496.    TO_CHAR(COUNT(*),'999,999,999,999'),
  1497.    TO_CHAR(SUM(BYTES),'999,999,999,999')
  1498. FROM DBA_SEGMENTS
  1499.    GROUP BY OWNER, TABLESPACE_NAME
  1500.    ORDER BY $sortfield
  1501. ";
  1502.    logit("   SQL = $sql");
  1503.    $cursor = $dbh->prepare($sql);
  1504.    $cursor->execute;
  1505.    while (($owner,$tablespace_name,$count,$bytes) = $cursor->fetchrow_array) {
  1506.       print "<TR><TD BGCOLOR='$cellcolor'><FONT COLOR='$fontcolor' SIZE='$fontsize' FACE='$font'><A HREF=$scriptname?database=$database&object_type=OBJECTREPORT&arg=$owner>$owner</A></TD>n";
  1507.       print "<TD BGCOLOR='$cellcolor'><FONT COLOR='$fontcolor' SIZE='$fontsize' FACE='$font'><A HREF=$scriptname?database=$database&object_type=TSINFO&arg=$tablespace_name>$tablespace_name</TD></A>n";
  1508.       print "<TD BGCOLOR='$cellcolor'><FONT COLOR='$fontcolor' SIZE='$fontsize' FACE='$font'>$count</TD>n";
  1509.       print "<TD BGCOLOR='$cellcolor'><FONT COLOR='$fontcolor' SIZE='$fontsize' FACE='$font'>$bytes</TD></TR>n";
  1510.    }
  1511.    $cursor->finish;
  1512.    print <<"EOF";
  1513.       </TABLE>
  1514.     </TD>
  1515.   </TR>
  1516. </TABLE>
  1517. EOF
  1518.    logit("Exit subroutine tsSpaceReport");
  1519.    
  1520. }
  1521. sub objectReport {
  1522.    logit("Enter subroutine objectReport");
  1523.    my ($sql1,$sql2,$count,$counter,$cursor1,$cursor2);
  1524.    my ($tablespace_name,$object_type,@tablespaces,$text,$link);
  1525.    my ($segment_name,$segment_type,$created,$last_ddl_time,$bytes,$extents);
  1526. # Show all objects for a particular user ordered by tablespace.
  1527. # This can be helpful for examining which tablespaces are expected
  1528. # to exist should you need to import this user's schema into a
  1529. # different database.
  1530.    $schema = $object_name unless ($schema);
  1531.    text("Object report for schema $schema ordered by tablespace.");
  1532.   $sql1 = "$copyright
  1533. SELECT DISTINCT 
  1534.    TABLESPACE_NAME 
  1535. FROM DBA_SEGMENTS
  1536.    WHERE OWNER = '$schema'
  1537.    AND SEGMENT_TYPE NOT IN ('CACHE',
  1538.     'ROLLBACK',
  1539.     'TEMPORARY')
  1540. ORDER BY TABLESPACE_NAME
  1541. ";
  1542.    $count=0;
  1543.    $cursor1 = $dbh->prepare($sql1); 
  1544.    $cursor1->execute;
  1545.    while ( $tablespace_name = $cursor1->fetchrow_array ) { 
  1546.       push @tablespaces, $tablespace_name;
  1547.       $count++;
  1548.    }
  1549.    $cursor1->finish;
  1550. # Exit if user has no objects anywhere.
  1551.    
  1552.    if ($count == 0) {
  1553.       print "<BR>$schema has no objects in this database.<BR>n";
  1554.       Footer();
  1555.       exit;
  1556.    } else {
  1557.       print "<BR>Objects of type CACHE or TEMPORARY not shown.<BR>n";
  1558.       print "$schema has objects in $count tablespace(s).<P></CENTER>n";
  1559.       print "<B>Summary report:</B><P><CENTER>n";
  1560.    }
  1561. # Print a summary report with object types and counts for each tablespace.
  1562. print "<TABLE>n";
  1563.    foreach $tablespace_name (@tablespaces) {
  1564.       print "  <TR VALIGN=TOP>n" if $counter == 0;
  1565.       print <<"EOF";
  1566.     <TD>
  1567.       <TABLE BORDER=0 BGCOLOR='$bordercolor' CELLPADDING=1 CELLSPACING=0>
  1568.         <TR>
  1569.           <TD WIDTH=100%>
  1570.             <TABLE BORDER=0 cellpadding=2 cellspacing=1>
  1571.               <TR>
  1572.                 <TD COLSPAN=2 ALIGN=CENTER BGCOLOR='$headingcolor'>
  1573.                 <FONT COLOR='$headingfontcolor' SIZE='$fontsize' FACE='$font'>$tablespace_name
  1574.                 </TD>
  1575.               </TR>
  1576.               <TH BGCOLOR='$headingcolor'><FONT COLOR='$headingfontcolor' SIZE='$fontsize' FACE='$headingfont'>Object type</TH>
  1577.               <TH BGCOLOR='$headingcolor'><FONT COLOR='$headingfontcolor' SIZE='$fontsize' FACE='$headingfont'>Count</TH>
  1578. EOF
  1579.       $sql1 = "$copyright
  1580. SELECT DISTINCT SEGMENT_TYPE 
  1581.    FROM DBA_SEGMENTS
  1582. WHERE OWNER = '$schema'
  1583. AND TABLESPACE_NAME = '$tablespace_name'
  1584. AND SEGMENT_TYPE NOT IN ('CACHE',
  1585.  'ROLLBACK',
  1586.  'TEMPORARY')
  1587. ";
  1588.       $cursor1=$dbh->prepare($sql1);
  1589.       $cursor1->execute;
  1590.       while ($object_type = $cursor1->fetchrow_array) {
  1591.          print "              <TR>n";
  1592.          print "                <TD BGCOLOR='$cellcolor'>n";
  1593.          print "                  <FONT COLOR='$fontcolor' SIZE='$fontsize' FACE='$font'>$object_typen";
  1594.          print "                </TD>n";
  1595.          $sql2 = "$copyright
  1596. SELECT COUNT(*) 
  1597.    FROM DBA_SEGMENTS 
  1598. WHERE OWNER = '$schema'
  1599. AND SEGMENT_TYPE = '$object_type'
  1600. AND TABLESPACE_NAME = '$tablespace_name'
  1601. ";
  1602.          $cursor2=$dbh->prepare($sql2);
  1603.          $cursor2->execute;
  1604.          $count = $cursor2->fetchrow_array;
  1605.          $cursor2->finish;
  1606.          print "                <TD BGCOLOR='$cellcolor'>n";
  1607.          print "                  <FONT COLOR='$fontcolor' SIZE='$fontsize' FACE='$font'>$countn";
  1608.          print "                </TD>n";
  1609.          print "              </TR>n";
  1610.       }
  1611.       $cursor1->finish;
  1612.       print "            </TABLE>n";
  1613.       $counter++;
  1614.       print "          </TD>n";
  1615.       print "        </TR>n";
  1616.       print "      </TABLE>n";
  1617.       print "    </TR>n" if $counter == 0;
  1618.       if ( $counter == 6 ) { $counter = 0 };
  1619.    }
  1620.    print "  </TR>n";
  1621.    print "</TABLE>n";
  1622.       print "</CENTER><P><HR WIDTH=100%><P><B>Detailed report:</B><P>n";
  1623.       foreach $tablespace_name (@tablespaces) {
  1624.    
  1625.       $sql2 = "$copyright
  1626. SELECT
  1627.    A.SEGMENT_NAME                                       "Object name",
  1628.    A.SEGMENT_TYPE                                       "Object type",
  1629.    TO_CHAR(B.CREATED,'Month DD, YYYY - HH24:MI')          "Created",
  1630.    TO_CHAR(B.LAST_DDL_TIME,'Month DD, YYYY - HH24:MI')    "Last DDL time",
  1631.    TO_CHAR(A.BYTES,'999,999,999,999')                   "Bytes",
  1632.    TO_CHAR(A.EXTENTS,'999,999,999,999')                 "Extents"
  1633. FROM DBA_SEGMENTS A, DBA_OBJECTS B
  1634.    WHERE A.TABLESPACE_NAME = '$tablespace_name'
  1635.    AND A.OWNER = '$schema'
  1636.    AND B.OWNER = '$schema'
  1637.    AND A.SEGMENT_NAME = B.OBJECT_NAME
  1638. ORDER BY A.SEGMENT_TYPE, A.SEGMENT_NAME
  1639. ";
  1640.       $text = "Tablespace $tablespace_name";
  1641.       $link = "";
  1642.       DisplayTable($sql2,$text,$link);
  1643.    }
  1644. # Show text based report
  1645.    print "<P>n";
  1646.    format STDOUT = 
  1647. @<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< @<<<<<<<<<<<<< @<<<<<<<<<<<<<<<<<<<< @>>>>>>>>>>>>>>>>>>> @>>>>>>>>>>>>>>
  1648. $segment_name,$segment_type,$created,$bytes,$extents
  1649. .
  1650.    print <<"EOF";
  1651. <TABLE BORDER=0 BGCOLOR='$bordercolor' CELLPADDING=1 CELLSPACING=0>
  1652.   <TR>
  1653.     <TD WIDTH=100%>
  1654.       <TABLE BORDER=0 CELLPADDING=2 CELLSPACING=1>
  1655.         <TR>
  1656.           <TD BGCOLOR='$cellcolor'>
  1657.             <PRE>
  1658. EOF
  1659.    print "Object usage for user $schema database $databasenn";
  1660.    foreach $tablespace_name (@tablespaces) {
  1661.       print "Tablespace $tablespace_namen";
  1662.       print "===========================nn";
  1663.       print "Object name                          Object type    Date created                       # Bytes       # Extentsn";
  1664.       print "===========                          ===========    ============                       =======       =========n";
  1665.       $sql = "$copyright
  1666. SELECT
  1667.    A.SEGMENT_NAME                                       "Object name",
  1668.    A.SEGMENT_TYPE                                       "Object type",
  1669.    TO_CHAR(B.CREATED,'Mon DD, YYYY - HH24:MI')          "Created",
  1670.    TO_CHAR(B.LAST_DDL_TIME,'Mon DD, YYYY - HH24:MI')    "Last DDL time",
  1671.    TO_CHAR(A.BYTES,'999,999,999,999')                   "Bytes",
  1672.    TO_CHAR(A.EXTENTS,'999,999,999,999')                 "Extents"
  1673. FROM DBA_SEGMENTS A, DBA_OBJECTS B
  1674.    WHERE A.TABLESPACE_NAME = '$tablespace_name'
  1675.    AND A.OWNER = '$schema'
  1676.    AND B.OWNER = '$schema'
  1677.    AND A.SEGMENT_NAME = B.OBJECT_NAME
  1678. ORDER BY A.SEGMENT_TYPE, A.SEGMENT_NAME
  1679. ";
  1680.       $cursor = $dbh->prepare($sql) or print "$DBI::errstrn";
  1681.       $cursor->execute;
  1682.       while (($segment_name,$segment_type,$created,$last_ddl_time,$bytes,$extents) = $cursor->fetchrow_array) {
  1683.          $segment_name =~ s/ //g;
  1684.          $segment_type =~ s/ //g;
  1685.          $bytes =~ s/ //g;
  1686.          $extents =~ s/ //g;
  1687. #         print "$segment_name,$segment_type,$created,$last_ddl_time,$bytes,$extentsn";
  1688.          write;
  1689.       }
  1690.       $cursor->finish;
  1691.       print "n";
  1692.    }
  1693.    print<<"EOF";
  1694.             </PRE>
  1695.           </TD>
  1696.         </TR>
  1697.       </TABLE>
  1698.     </TD>
  1699.   </TR>
  1700. </TABLE> 
  1701. EOF
  1702.       
  1703.    logit("Exit subroutine objectReport");
  1704. }
  1705. sub showObjects {
  1706.    logit("Enter subroutine showObjects");
  1707.    my ($sql,$text,$link,$infotext,$nulltext,$count,$table_name);
  1708.    my ($cursor);
  1709.    logit("   Object is a $object_name");
  1710. # Object types with spaces are not +'d at this point.
  1711.    $object_type = $object_name;
  1712. # Check for the different types of tables.
  1713. # If Oracle8, the table name will not show up in DBA_SEGMENTS if
  1714. # the table is partitioned, so we will select from DBA_PART_TABLES.
  1715.    if ($object_type eq "TABLE") {
  1716.       if ($oracle8) {
  1717.          $sql = "$copyright
  1718. SELECT
  1719.    TABLE_NAME                           "Table name",
  1720.    DEF_TABLESPACE_NAME                  "Def. tablespace name",
  1721.    PARTITIONING_TYPE                    "Partitioning type",
  1722.    PARTITION_COUNT                      "Partition count"
  1723. FROM DBA_PART_TABLES
  1724.    WHERE OWNER = '$schema'
  1725. ";
  1726.          $infotext = "No partitioned tables in this schema.";
  1727.          $text = "Partitioned tables.";
  1728.          $link = "$scriptname?database=$database&schema=$schema&object_type=$object_type";
  1729.          DisplayTable($sql,$text,$link,$infotext);
  1730. # Check for Index Organized Tables, because they won't show up in DBA_SEGMENTS
  1731.          $sql = "$copyright
  1732. SELECT
  1733.    TABLE_NAME "Table name"
  1734. FROM DBA_TABLES
  1735.    WHERE OWNER = '$schema'
  1736. AND IOT_TYPE = 'IOT'
  1737. ";
  1738.          $infotext = "No Index Organized Tables in this schema.";
  1739.          $text = "Index Organized Tables.";
  1740.          $link = "$scriptname?database=$database&schema=$schema&object_type=$object_name";
  1741.          DisplayTable($sql,$text,$link,$infotext);
  1742.       }
  1743. # Now, show the normal tables.
  1744.       logit("   Start standard tables");
  1745.       $sql = "$copyright
  1746. SELECT
  1747.    SEGMENT_NAME                         "Object name",
  1748.    TABLESPACE_NAME                      "Tablespace name",
  1749.    TO_CHAR(BYTES,'999,999,999,999')     "Bytes"
  1750. FROM DBA_SEGMENTS
  1751.    WHERE OWNER = '$schema'
  1752.    AND SEGMENT_TYPE = '$object_type'
  1753. ORDER BY SEGMENT_NAME
  1754. ";
  1755.       $text = "Standard tables.";
  1756.       $infotext = "No standard tables in this schema.";
  1757.       $link = "$scriptname?database=$database&schema=$schema&object_type=$object_name";
  1758.       DisplayTable($sql,$text,$link,$infotext);
  1759.       exit;
  1760.    }
  1761. # If object is an index, show the space used
  1762.    if ($object_type eq "INDEX") {
  1763.       if ($oracle8) {
  1764. # Show partitioned indexes.
  1765.          $sql = "$copyright
  1766. SELECT
  1767.    INDEX_NAME                           "Index name",
  1768.    DEF_TABLESPACE_NAME                  "Def. tablespace name",
  1769.    PARTITIONING_TYPE                    "Partitioning type",
  1770.    PARTITION_COUNT                      "Partition count"
  1771. FROM DBA_PART_INDEXES
  1772.    WHERE OWNER = '$schema'
  1773. ";
  1774.          $infotext = "No partitioned indexes in this schema.";
  1775.          $text = "Partitioned indexes.";
  1776.          $link = "$scriptname?database=$database&schema=$schema&object_type=$object_type";
  1777.          DisplayTable($sql,$text,$link,$infotext);
  1778. # Show bitmapped indexes
  1779.          $sql = "$copyright
  1780. SELECT
  1781.    INDEX_NAME "Index name",
  1782.    TABLESPACE_NAME "Tablespace name"
  1783. FROM DBA_INDEXES
  1784.    WHERE OWNER = '$schema'
  1785.    AND INDEX_TYPE = 'BITMAP'
  1786. ORDER BY INDEX_NAME
  1787. ";
  1788.          $text = "Bitmapped indexes.";
  1789.          $infotext = "No bitmapped indexes in this schema.";
  1790.          $link = "$scriptname?database=$database&schema=$schema&object_type=$object_type";
  1791.          DisplayTable($sql,$text,$link,$infotext);
  1792. # Show IOT indexes
  1793.          $sql = "$copyright
  1794. SELECT
  1795.    INDEX_NAME "Index name",
  1796.    TABLESPACE_NAME "Tablespace name"
  1797. FROM DBA_INDEXES
  1798.    WHERE OWNER = '$schema'
  1799.    AND INDEX_TYPE LIKE '%IOT%'
  1800. ORDER BY INDEX_NAME
  1801. ";
  1802.          $text = "Index Organized Table indexes.";
  1803.          $infotext = "No Index Organized Table indexes in this schema.";
  1804.          $link = "$scriptname?database=$database&schema=$schema&object_type=$object_type";
  1805.          DisplayTable($sql,$text,$link,$infotext);
  1806. # Show standard indexes
  1807.          $sql = "$copyright
  1808. SELECT
  1809.    INDEX_NAME "Object name",
  1810.    TABLESPACE_NAME "Tablespace name"
  1811. FROM DBA_INDEXES
  1812.    WHERE OWNER = '$schema'
  1813.    AND INDEX_TYPE != 'BITMAP'
  1814.    AND INDEX_TYPE NOT LIKE '%IOT%'
  1815. ";
  1816.          $text = "Standard indexes.";
  1817.          $infotext = "No standard indexes in this schema.";
  1818.          $link = "$scriptname?database=$database&schema=$schema&object_type=$object_type";
  1819.          DisplayTable($sql,$text,$link,$infotext);
  1820.          exit;
  1821.       } else {
  1822.        
  1823. # We are Oracle7
  1824.          $sql = "$copyright
  1825. SELECT
  1826.    INDEX_NAME "Object name",
  1827.    TABLESPACE_NAME "Tablespace name"
  1828. FROM DBA_INDEXES
  1829.    WHERE OWNER = '$schema'
  1830. ";
  1831.          $text = "Select an index for more info.";
  1832.          $infotext = "No standard indexes in this schema.";
  1833.          $link = "$scriptname?database=$database&schema=$schema&object_type=$object_type";
  1834.          DisplayTable($sql,$text,$link,$infotext);
  1835.          exit;
  1836.       }
  1837.    }
  1838. # If object is of type partitioned, then
  1839. # show the subobject as well.
  1840.    if ($object_type eq "TABLE PARTITION") {
  1841.       $sql = "$copyright
  1842. SELECT
  1843.    TABLE_NAME                                   "Table name",
  1844.    PARTITION_NAME                               "Partition name",
  1845.    TABLE_OWNER                                  "Owner",
  1846.    TABLESPACE_NAME                              "Tablespace",
  1847.    PARTITION_POSITION                           "Position",
  1848.    TO_CHAR(INITIAL_EXTENT,'999,999,999,999')    "Initial",
  1849.    TO_CHAR(NEXT_EXTENT,'999,999,999,999')       "Next",
  1850.    TO_CHAR(MAX_EXTENT,'999,999,999,999')        "Max extents",
  1851.    PCT_INCREASE                                 "Pct increase",
  1852.    HIGH_VALUE                                   "High value",
  1853.    HIGH_VALUE_LENGTH                            "High value length",
  1854.    LOGGING                                      "Logging"
  1855. FROM DBA_TAB_PARTITIONS
  1856.    WHERE TABLE_OWNER = '$schema'
  1857. ORDER BY TABLE_NAME
  1858. ";
  1859.       $text = "Select a partition for info about the parent table.";
  1860.       $link = "$scriptname?database=$database&schema=$schema&object_type=TABLE";
  1861.       DisplayTable($sql,$text,$link,$infotext);
  1862.       logit("   Link = $link");
  1863.       exit;
  1864.    }
  1865.    if ($object_type eq "INDEX PARTITION") {
  1866.       $sql = "$copyright
  1867. SELECT
  1868.    INDEX_NAME "Index name",
  1869.    PARTITION_NAME                               "Partition name",
  1870.    TABLESPACE_NAME                              "Tablespace",
  1871.    PARTITION_POSITION                           "Position",
  1872.    TO_CHAR(INITIAL_EXTENT,'999,999,999,999')    "Initial",
  1873.    TO_CHAR(NEXT_EXTENT,'999,999,999,999')       "Next",
  1874.    TO_CHAR(MAX_EXTENT,'999,999,999,999')        "Max extents",
  1875.    PCT_INCREASE                                 "Pct increase",
  1876.    HIGH_VALUE                                   "High value",
  1877.    HIGH_VALUE_LENGTH                            "High value length",
  1878.    LOGGING                                      "Logging"
  1879. FROM DBA_IND_PARTITIONS
  1880.    WHERE INDEX_OWNER = '$schema'
  1881. ORDER BY INDEX_NAME
  1882. ";
  1883.       $text = "Select a partition for info about the parent index.";
  1884.       $link = "$scriptname?database=$database&schema=$schema&object_type=INDEX";
  1885.       DisplayTable($sql,$text,$link,$infotext);
  1886.       logit("   Link = $link");
  1887.       exit;
  1888.    }
  1889. # Show all for sequences
  1890.    if ($object_type eq "SEQUENCE") {
  1891.        $sql = "$copyright
  1892. SELECT
  1893.    SEQUENCE_NAME "Sequence name",
  1894.    MIN_VALUE                                    "Min value",
  1895.    MAX_VALUE                                    "Max value",
  1896.    INCREMENT_BY                                 "Increment by",
  1897.    CYCLE_FLAG                                   "Cycle flag",
  1898.    ORDER_FLAG                                   "Order flag",
  1899.    CACHE_SIZE                                   "Cache size",
  1900.    LAST_NUMBER                                  "Last number"
  1901. FROM DBA_SEQUENCES
  1902.    WHERE SEQUENCE_OWNER = '$schema'
  1903. ";
  1904.       $text = "Sequences owned by $schema..";
  1905.       DisplayTable($sql,$text);
  1906.       exit;
  1907.    }
  1908. # Show public synonym info
  1909.    if ($object_type eq "PUBLIC SYNONYMS") {
  1910.       $sql = "$copyright
  1911. SELECT
  1912.    SYNONYM_NAME "Synonym name",
  1913.    TABLE_NAME "Object name",
  1914.    TABLE_OWNER "Object owner",
  1915.    DB_LINK "DB link"
  1916. FROM DBA_SYNONYMS
  1917.    WHERE OWNER = 'PUBLIC'
  1918.    AND TABLE_OWNER = '$schema'
  1919. ";
  1920.       $text = "All public synonyms pointing to $schema objects.";
  1921.       $link = "";
  1922.       $infotext = "No public synonyms are pointing to $schema objects.";
  1923.       DisplayTable($sql,$text,$link,$infotext);
  1924.    }
  1925. # Default sql
  1926.       $sql = "$copyright
  1927. SELECT 
  1928.    OBJECT_NAME        "Object name" 
  1929. FROM DBA_OBJECTS 
  1930.    WHERE OWNER = '$schema' 
  1931.    AND OBJECT_TYPE = '$object_type'
  1932. ";
  1933.    $link = "$scriptname?database=$database&schema=$schema&object_type=$object_name";
  1934.    DisplayTable($sql,$text,$link);
  1935.    logit("Exit subroutine showObjects");
  1936. }
  1937. sub showSynonym {
  1938.    logit("Enter subroutine showSynonym");
  1939.    my ($sql,$text,$link);
  1940. # General synonym info
  1941.    $sql = "$copyright
  1942. SELECT 
  1943.    SYNONYM_NAME "Synonym name", 
  1944.    TABLE_NAME "Object name", 
  1945.    TABLE_OWNER "Table owner", 
  1946.    DB_LINK "Database link"
  1947. FROM DBA_SYNONYMS 
  1948.    WHERE SYNONYM_NAME = '$object_name' 
  1949.    AND OWNER = '$schema'
  1950. ";
  1951.    $text = "";
  1952.    $link = "";
  1953.    DisplayTable($sql,$text,$link);
  1954.    logit("Exit subroutine showSynonym");
  1955. }
  1956. sub showTablespaces {
  1957.    logit("Enter subroutine showTablespaces");
  1958.    my ($sql,$text,$link);
  1959. # Tablespace graph button
  1960. print <<"EOF";
  1961. <TABLE BORDER=0 CELLPADDING=0 CELLSPACING=0>
  1962.   <TR>
  1963.     <TD ALIGN=CENTER>
  1964.       <FORM METHOD="GET" ACTION="$scriptname">
  1965.         <FONT COLOR='$fontcolor' SIZE='$fontsize' FACE='$font'>
  1966.         <INPUT TYPE="HIDDEN" NAME="database" VALUE="$database">
  1967.         <INPUT TYPE="HIDDEN" NAME="object_type" VALUE="TSGRAPH">
  1968.         <INPUT TYPE="SUBMIT" NAME="tsgraph" VALUE="Tablespace allocation graph">
  1969.       </FORM>
  1970.     </TD>
  1971.   </TR>
  1972. </TABLE>
  1973. EOF
  1974.    $sql = "$copyright
  1975. SELECT
  1976.    TO_CHAR(SUM(BYTES),'999,999,999,999,999') "Total allocated space"
  1977. FROM DBA_DATA_FILES
  1978. ";
  1979.    $text = "";
  1980.    $link = "";
  1981.    DisplayTable($sql,$text,$link);
  1982. # General tablespace information
  1983.    $sql = "$copyright
  1984. SELECT
  1985.    TABLESPACE_NAME "Tablespace name",
  1986.    TO_CHAR(INITIAL_EXTENT,'999,999,999,999') "Initial extent",
  1987.    TO_CHAR(NEXT_EXTENT,'999,999,999,999') "Next extent",
  1988.    TO_CHAR(MAX_EXTENTS,'999,999,999,999') "Max extents",
  1989.    PCT_INCREASE "% increase",
  1990.    STATUS "Status",
  1991.    CONTENTS "Contents"
  1992.    FROM DBA_TABLESPACES
  1993. ORDER BY TABLESPACE_NAME
  1994. ";
  1995.    $sql = "$copyright
  1996. SELECT
  1997.    DTS.TABLESPACE_NAME "Tablespace name",
  1998.    TO_CHAR(DTS.INITIAL_EXTENT,'999,999,999,999') "Initial extent",
  1999.    TO_CHAR(DTS.NEXT_EXTENT,'999,999,999,999') "Next extent",
  2000.    TO_CHAR(DTS.MAX_EXTENTS,'999,999,999,999') "Max extents",
  2001.    TO_CHAR(TSD.DFLMINLEN*$db_block_size,'999,999,999,999') "Minimum extent",
  2002.    DTS.PCT_INCREASE "% increase",
  2003.    DTS.STATUS "Status",
  2004.    DTS.CONTENTS "Contents",
  2005.    DTS.LOGGING "Logging?"
  2006. FROM DBA_TABLESPACES DTS, SYS.TS$ TSD
  2007.    WHERE DTS.TABLESPACE_NAME = TSD.NAME
  2008. ORDER BY TABLESPACE_NAME
  2009. " if ($oracle8);
  2010.    $sql = "$copyright
  2011. SELECT
  2012.    DTS.TABLESPACE_NAME "Tablespace name",
  2013.    TO_CHAR(DTS.INITIAL_EXTENT,'999,999,999,999') "Initial extent",
  2014.    TO_CHAR(DTS.NEXT_EXTENT,'999,999,999,999') "Next extent",
  2015.    TO_CHAR(DTS.MAX_EXTENTS,'999,999,999,999') "Max extents",
  2016.    TO_CHAR(TSD.DFLMINLEN*$db_block_size,'999,999,999,999') "Minimum extent",
  2017.    DTS.PCT_INCREASE "% increase",
  2018.    DTS.STATUS "Status",
  2019.    DTS.CONTENTS "Contents",
  2020.    DTS.LOGGING "Logging?",
  2021.    DTS.EXTENT_MANAGEMENT "Ext. Mgmt",
  2022.    DTS.ALLOCATION_TYPE "Alloc type",
  2023.    DTS.PLUGGED_IN "Plugged?"
  2024. FROM DBA_TABLESPACES DTS, SYS.TS$ TSD
  2025.    WHERE DTS.TABLESPACE_NAME = TSD.NAME
  2026. ORDER BY TABLESPACE_NAME
  2027. " if ($oracle8i);
  2028.    $text = "Tablespace information: Database $database";
  2029.    $link = "$scriptname?database=$database&object_type=TSINFO";
  2030.    DisplayTable($sql,$text,$link);
  2031.    logit("Exit subroutine showTablespaces");
  2032. }
  2033. sub showTSinfo {
  2034.    logit("Enter subroutine showTSinfo");
  2035.    my ($sql,$cursor,$foo,$text,$link,$infotext);
  2036.    refreshButton();
  2037. # Display a button for a screen with a datafile fragmentation map.
  2038.    print <<"EOF";
  2039. <TABLE BORDER=0 CELLPADDING=0 CELLSPACING=0>
  2040.   <TR>
  2041.     <TD ALIGN=CENTER>
  2042.       <FORM METHOD="GET" ACTION="$scriptname">
  2043.         <FONT COLOR='$fontcolor' SIZE='$fontsize' FACE='$font'>
  2044.         <INPUT TYPE="HIDDEN" NAME="object_type" VALUE="FRAGMAP">
  2045.         <INPUT TYPE="HIDDEN" NAME="database" VALUE="$database">
  2046.         <INPUT TYPE="HIDDEN" NAME="arg" VALUE="$object_name">
  2047.         <INPUT TYPE="HIDDEN" NAME="whereclause" VALUE="tablespace">
  2048.         <INPUT TYPE="SUBMIT" NAME="fragmap" VALUE="Fragmentation map">
  2049.       </FORM>
  2050.     </TD>
  2051.   </TR>
  2052. </TABLE>
  2053. EOF
  2054. # Tablespace information
  2055.    $sql = "$copyright
  2056. SELECT
  2057.    TABLESPACE_NAME                              "Tablespace name",
  2058.    TO_CHAR(INITIAL_EXTENT,'999,999,999,999')    "Initial extent",
  2059.    TO_CHAR(NEXT_EXTENT,'999,999,999,999')       "Next extent",
  2060.    TO_CHAR(MAX_EXTENTS,'999,999,999,999')       "Max extents",
  2061.    PCT_INCREASE                                 "% increase",
  2062.    STATUS                                       "Status",
  2063.    CONTENTS                                     "Contents"
  2064.    FROM DBA_TABLESPACES
  2065. WHERE TABLESPACE_NAME = '$object_name'
  2066. ";
  2067.    $sql = "$copyright
  2068. SELECT
  2069.    DTS.TABLESPACE_NAME "Tablespace name",
  2070.    TO_CHAR(DTS.INITIAL_EXTENT,'999,999,999,999') "Initial extent",
  2071.    TO_CHAR(DTS.NEXT_EXTENT,'999,999,999,999') "Next extent",
  2072.    TO_CHAR(DTS.MAX_EXTENTS,'999,999,999,999') "Max extents",
  2073.    TO_CHAR(TSD.DFLMINLEN*$db_block_size,'999,999,999,999') "Minimum extent",
  2074.    DTS.PCT_INCREASE "% increase",
  2075.    DTS.STATUS "Status",
  2076.    DTS.CONTENTS "Contents",
  2077.    DTS.LOGGING "Logging?"
  2078. FROM DBA_TABLESPACES DTS, SYS.TS$ TSD
  2079.    WHERE DTS.TABLESPACE_NAME = '$object_name'
  2080.    AND TSD.NAME = '$object_name'
  2081. " if ($oracle8);
  2082.    $sql = "$copyright
  2083. SELECT
  2084.    DTS.TABLESPACE_NAME "Tablespace name",
  2085.    TO_CHAR(DTS.INITIAL_EXTENT,'999,999,999,999') "Initial extent",
  2086.    TO_CHAR(DTS.NEXT_EXTENT,'999,999,999,999') "Next extent",
  2087.    TO_CHAR(DTS.MAX_EXTENTS,'999,999,999,999') "Max extents",
  2088.    TO_CHAR(TSD.DFLMINLEN*$db_block_size,'999,999,999,999') "Minimum extent",
  2089.    DTS.PCT_INCREASE "% increase",
  2090.    DTS.STATUS "Status",
  2091.    DTS.CONTENTS "Contents",
  2092.    DTS.LOGGING "Logging?",
  2093.    DTS.EXTENT_MANAGEMENT "Ext. Mgmt",
  2094.    DTS.ALLOCATION_TYPE "Alloc type",
  2095.    DTS.PLUGGED_IN "Plugged?"
  2096. FROM DBA_TABLESPACES DTS, SYS.TS$ TSD
  2097.    WHERE DTS.TABLESPACE_NAME = '$object_name'
  2098.    AND TSD.NAME = '$object_name'
  2099. " if ($oracle8i);
  2100.    $text = "General information: Tablespace $object_name";
  2101.    $link = "$scriptname?database=$database&object_type=TSDDL";
  2102.    DisplayTable($sql,$text,$link);
  2103. # Space allocation
  2104.    $sql = "$copyright
  2105. SELECT
  2106.    DF.TABLESPACE_NAME "Tablespace name",
  2107.    TO_CHAR(DF.BYTES,'999,999,999,999') "Bytes allocated",
  2108.    NVL(TO_CHAR(DF.BYTES-SUM(FS.BYTES),'999,999,999,999'),    
  2109.         TO_CHAR(DF.BYTES,'999,999,999,999')) "Bytes used", 
  2110.    NVL(TO_CHAR(SUM(FS.BYTES),'999,999,999,999'),0) "Bytes free",
  2111.    NVL(ROUND((DF.BYTES-SUM(FS.BYTES))*100/DF.BYTES),100)||'%' "Percent used",
  2112.    NVL(ROUND(SUM(FS.BYTES)*100/DF.BYTES),0)||'%' "Percent free" 
  2113. FROM DBA_FREE_SPACE FS,
  2114.    (SELECT TABLESPACE_NAME, SUM(BYTES) BYTES FROM DBA_DATA_FILES GROUP BY
  2115. TABLESPACE_NAME ) DF
  2116. WHERE FS.TABLESPACE_NAME (+) = DF.TABLESPACE_NAME
  2117. AND DF.TABLESPACE_NAME = '$object_name'
  2118. GROUP BY DF.TABLESPACE_NAME, DF.BYTES
  2119. ORDER BY "Percent free"
  2120. ";
  2121.    $text = "Space allocation";
  2122.    $link = "";
  2123.    DisplayTable($sql,$text,$link);
  2124. # Fragmentation / general info
  2125. if ($oracle8) {
  2126.    $sql = "$copyright
  2127. SELECT 
  2128.    A.FILE_NAME "File name",
  2129.    B.FILE_ID "File #", 
  2130.    TO_CHAR(A.BYTES,'999,999,999,999') "Bytes",
  2131.    TO_CHAR(MAX(B.BYTES),'999,999,999,999') "Largest free chunk", 
  2132.    TO_CHAR(MIN(B.BYTES),'999,999,999,999') "Smallest free chunk",
  2133.    COUNT(*) "Pieces",
  2134.    DECODE(A.AUTOEXTENSIBLE,
  2135.                            'YES','Yes',
  2136.                            'NO','No') "Xtend?",
  2137.    TO_CHAR(A.MAXBYTES,'999,999,999,999') "Max bytes",
  2138.    TO_CHAR(A.INCREMENT_BY*$db_block_size,'999,999,999,999') "Increment"
  2139. FROM DBA_DATA_FILES A, DBA_FREE_SPACE B
  2140. WHERE A.FILE_ID = B.FILE_ID
  2141. AND B.TABLESPACE_NAME = '$object_name'
  2142. GROUP BY A.FILE_NAME, B.FILE_ID, A.BYTES,A.AUTOEXTENSIBLE,A.MAXBYTES,A.INCREMENT_BY
  2143. ";
  2144.    } else {
  2145.    $sql = "$copyright
  2146. SELECT 
  2147.    A.FILE_NAME "File name",
  2148.    B.FILE_ID "File #", 
  2149.    TO_CHAR(A.BYTES,'999,999,999,999') "Bytes",
  2150.    TO_CHAR(MAX(B.BYTES),'999,999,999,999') "Largest free chunk", 
  2151.    TO_CHAR(MIN(B.BYTES),'999,999,999,999') "Smallest free chunk",
  2152.    COUNT(*) "Pieces"
  2153. FROM DBA_DATA_FILES A, DBA_FREE_SPACE B
  2154. WHERE A.FILE_ID = B.FILE_ID
  2155. AND B.TABLESPACE_NAME = '$object_name'
  2156. GROUP BY A.FILE_NAME, B.FILE_ID, A.BYTES
  2157. ";
  2158. }
  2159.    $text = "Tablespace (datafile) fragmentation";
  2160.    $link = "$scriptname?database=$database&object_type=DATAFILE";
  2161.    DisplayTable($sql,$text,$link);
  2162. # Tablespace graph button
  2163. print <<"EOF";
  2164. <BR>
  2165. <TABLE BORDER=0 CELLPADDING=0 CELLSPACING=0>
  2166.   <TR>
  2167.     <TD ALIGN=CENTER>
  2168.       <FORM METHOD="GET" ACTION="$scriptname">
  2169.         <FONT COLOR='$fontcolor' SIZE='$fontsize' FACE='$font'>
  2170.         <INPUT TYPE="HIDDEN" NAME="database" VALUE="$database">
  2171.         <INPUT TYPE="HIDDEN" NAME="object_type" VALUE="TSFILEGRAPH">
  2172.         <INPUT TYPE="HIDDEN" NAME="schema" VALUE="$object_name">
  2173.         <INPUT TYPE="SUBMIT" NAME="tsfilegraph" VALUE="Datafile information graphs">
  2174.       </FORM>
  2175.     </TD>
  2176.   </TR>
  2177. </TABLE
  2178. EOF
  2179.    $sql = "$copyright
  2180. SELECT DISTINCT
  2181.    TO_CHAR(BYTES,'999,999,999,999') "Extent size",
  2182.    TO_CHAR(COUNT(*),'999,999,999,999') "# extents"
  2183. FROM DBA_EXTENTS
  2184.    WHERE TABLESPACE_NAME = '$object_name'
  2185. GROUP BY BYTES 
  2186. ORDER BY 1 DESC
  2187. ";
  2188.    $text = "Extent sizes / counts contained in this tablespace.";
  2189.    $foo = DisplayTable($sql,$text);
  2190. # Added this to check for DBA_FREE_SPACE
  2191. # returning a null value if there is no
  2192. # free space
  2193.    $sql = "$copyright
  2194. SELECT MAX(BYTES)
  2195.    FROM DBA_FREE_SPACE
  2196. WHERE TABLESPACE_NAME = '$object_name'
  2197. ";
  2198.    $cursor=$dbh->prepare($sql);
  2199.    $cursor->execute;
  2200.    $foo = $cursor->fetchrow_array;
  2201.    if ($foo) {
  2202.    
  2203. # Objects in the tablespace with next extent sizes larger than the largest
  2204. # free extent in the tablespace. Allocating a next extent for these objects
  2205. # will fail.
  2206.       $sql = "$copyright
  2207. SELECT 
  2208.    SEGMENT_NAME "Object name", 
  2209.    OWNER "Owner",
  2210.    TO_CHAR(NEXT_EXTENT,'999,999,999,999') "Next extent"
  2211. FROM DBA_SEGMENTS
  2212.    WHERE TABLESPACE_NAME = '$object_name'
  2213.    AND NEXT_EXTENT > (SELECT MAX(BYTES) FROM DBA_FREE_SPACE
  2214. WHERE TABLESPACE_NAME = '$object_name')
  2215. ";
  2216.       $text = "Objects that will fail to allocate a next extent";
  2217.       $link = "";
  2218.       $infotext = "No objects in $object_name will fail to allocate a next extent.";
  2219.       DisplayTable($sql,$text,$link,$infotext);
  2220.     } else {
  2221.       message("Warning: No objects can allocate an extent. Add a datafile.");
  2222.    }
  2223.    undef $foo;
  2224. # Objects in the tablespace that are approaching their max_extents limit.
  2225.    $sql = "$copyright
  2226. SELECT 
  2227.    SEGMENT_NAME "Object name",
  2228.    OWNER "Owner",
  2229.    SEGMENT_TYPE "Object type",
  2230.    TO_CHAR(EXTENTS,'999,999,999,999') "Extents",
  2231.    TO_CHAR(MAX_EXTENTS,'999,999,999,999') "Max extents"
  2232. FROM DBA_SEGMENTS
  2233.    WHERE TABLESPACE_NAME = '$object_name'
  2234.    AND EXTENTS > (MAX_EXTENTS-25)
  2235.    AND SEGMENT_TYPE != 'CACHE'
  2236. ";
  2237.    $text = "Objects that are approaching their max_extents limit";
  2238.    $link = "";
  2239.    $infotext = "No objects in $object_name have extents > ( max_extents - 25 )";
  2240.    DisplayTable($sql,$text,$link,$infotext);
  2241.    $sql = "$copyright
  2242. SELECT 
  2243.    A.SEGMENT_NAME "Object name",
  2244.    A.SEGMENT_TYPE "Object type",
  2245.    A.OWNER "Owner",
  2246.    TO_CHAR(B.CREATED,'Month DD, YYYY - HH24:MI') "Created",
  2247.    TO_CHAR(B.LAST_DDL_TIME,'Month DD, YYYY - HH24:MI')    "Last DDL time",
  2248.    TO_CHAR(A.BYTES,'999,999,999,999') "Bytes",
  2249.    TO_CHAR(A.INITIAL_EXTENT,'999,999,999,999') "Initial extent",
  2250.    TO_CHAR(A.NEXT_EXTENT,'999,999,999,999') "Next extent",
  2251.    TO_CHAR(A.EXTENTS,'999,999,999,999') "Extents"
  2252. FROM DBA_SEGMENTS A, DBA_OBJECTS B
  2253.    WHERE A.TABLESPACE_NAME = '$object_name'
  2254.    AND A.SEGMENT_NAME = B.OBJECT_NAME
  2255.    AND A.SEGMENT_TYPE = B.OBJECT_TYPE
  2256.    AND A.OWNER = B.OWNER
  2257. ORDER BY A.OWNER, A.SEGMENT_TYPE, A.SEGMENT_NAME
  2258. ";
  2259.    $text = "Object list";
  2260.    $link = "";
  2261.    $infotext = "Tablespace $object_name has no objects.";
  2262.    ObjectTable($sql,$text,$infotext);
  2263.    logit("Exit subroutine showTSinfo");
  2264. }
  2265. sub showFile {
  2266.    logit("Enter subroutine showFile");
  2267.    my ($sql,$text,$link,$infotext);
  2268. # Display a button for a screen with a datafile fragmentation map.
  2269.    print <<"EOF";
  2270. <TABLE BORDER=0 CELLPADDING=0 CELLSPACING=0>
  2271.   <TR>
  2272.     <TD ALIGN=CENTER>
  2273.       <FORM METHOD="GET" ACTION="$scriptname">
  2274.         <FONT COLOR='$fontcolor' SIZE='$fontsize' FACE='$font'>
  2275.         <INPUT TYPE="HIDDEN" NAME="database" VALUE="$database">
  2276.         <INPUT TYPE="HIDDEN" NAME="object_type" VALUE="FRAGMAP">
  2277.         <INPUT TYPE="HIDDEN" NAME="arg" VALUE="$object_name">
  2278.         <INPUT TYPE="HIDDEN" NAME="whereclause" VALUE="datafile">
  2279.         <INPUT TYPE="SUBMIT" NAME="fragmap" VALUE="Fragmentation map">
  2280.       </FORM>
  2281.     </TD>
  2282.   </TR>
  2283. </TABLE>
  2284. EOF
  2285. # Specific datafile information
  2286.    $sql = "$copyright
  2287. SELECT 
  2288.    B.FILE_NAME "File name",
  2289.    TO_CHAR(A.CREATE_BYTES,'999,999,999,999') "Creation size",
  2290.    TO_CHAR(A.BYTES,'999,999,999,999') "Current size",
  2291.    TO_CHAR(B.BLOCKS,'999,999,999,999') "Blocks",
  2292.    B.TABLESPACE_NAME "Tablespace_name",
  2293.    B.STATUS "Status"
  2294. FROM V$DATAFILE A, DBA_DATA_FILES B
  2295.    WHERE B.FILE_NAME = '$object_name'
  2296.    AND A.FILE# = B.FILE_ID
  2297. ";
  2298.    $text = "General information";
  2299.    $link = "";
  2300.    DisplayTable($sql,$text,$link);
  2301.    $sql = "$copyright
  2302. SELECT 
  2303.    TO_CHAR(A.PHYRDS,'999,999,999,999') "Physical reads#",
  2304.    TO_CHAR(A.PHYWRTS,'999,999,999,999') "Physical writes#",
  2305.    TO_CHAR(A.PHYBLKRD*$db_block_size,'999,999,999,999') "Bytes read",
  2306.    TO_CHAR(A.PHYBLKWRT*$db_block_size,'999,999,999,999') "Bytes written"
  2307. FROM V$FILESTAT A, DBA_DATA_FILES B
  2308.    WHERE B.FILE_NAME = '$object_name'
  2309.    AND A.FILE# = B.FILE_ID
  2310. ";
  2311.    $text = "I/O stats since database startup";
  2312.    $link = "";
  2313.    DisplayTable($sql,$text,$link);
  2314. #   $text = "Historical I/O stats.";
  2315. #   DisplayGraph("dbfile",$object_name,$text);
  2316.    $sql = "$copyright
  2317. SELECT 
  2318.    TO_CHAR(NEXT_EXTENT,'999,999,999,999') "Next extent"
  2319. FROM DBA_TABLESPACES
  2320.     WHERE TABLESPACE_NAME =  
  2321. (SELECT 
  2322.    TABLESPACE_NAME FROM DBA_DATA_FILES
  2323. WHERE FILE_NAME = '$object_name')
  2324. ";
  2325.    $text = "Next extent size of tablespace";
  2326.    $link = "";
  2327.    DisplayTable($sql,$text,$link);
  2328.    
  2329.    $sql = "$copyright
  2330. SELECT 
  2331.    TO_CHAR(BYTES,'999,999,999,999') "Chunk size (bytes)",
  2332.    TO_CHAR(BLOCKS,'999,999,999,999') "Blocks"
  2333. FROM DBA_FREE_SPACE
  2334.    WHERE FILE_ID  = 
  2335. (SELECT 
  2336.    FILE_ID FROM DBA_DATA_FILES 
  2337.       WHERE FILE_NAME = '$object_name')
  2338.       AND ROWNUM <= 10
  2339.    ORDER BY BYTES DESC
  2340. ";
  2341.    $text = "Free space (Top ten)";
  2342.    $link = "";
  2343.    $infotext = "There are no free chunks of data in this datafile.";
  2344.    DisplayTable($sql,$text,$link,$infotext);
  2345.    $sql = "$copyright
  2346. SELECT DISTINCT
  2347.    SEGMENT_NAME "Segment name",
  2348.    SEGMENT_TYPE "Segment type",
  2349.    OWNER "Owner",
  2350.    TABLESPACE_NAME "Tablespace name"
  2351. FROM DBA_EXTENTS
  2352.    WHERE FILE_ID = (
  2353. SELECT FILE_ID FROM DBA_DATA_FILES
  2354.    WHERE FILE_NAME = '$object_name')
  2355. ";
  2356.    $text = "Objects which have extents in this datafile.";
  2357.    $infotext = "There are no objects with extents in this datafile.";
  2358.    ObjectTable($sql,$text,$infotext);
  2359.    logit("Exit subroutine showFile");
  2360. }
  2361. sub runSQL {
  2362.    logit("Enter subroutine runSQL");
  2363.    my ($sql,$cursor,$rows,$text,$link,$infotext,@statements,$statement,$error);
  2364.    $_ = shift;
  2365.    $_ = $object_name unless $_;
  2366. # Get rid of trailing whitespace
  2367.    s/s+$//;
  2368.    @statements = split /;/;
  2369.    foreach $_ (@statements) {
  2370. # Get rid of leading whitespace and newlines
  2371.       s/^s+//;
  2372. # If the command is "DESCRIBE"
  2373.    if (/^desc/i) {
  2374.       @_ = split;
  2375.       Describe("$_[1]");
  2376.       next;
  2377.    }
  2378.    loginfo("   SQL:n$_");
  2379.       
  2380. print <<"EOF";
  2381. <TABLE BGCOLOR='$bordercolor' WIDTH="100" CELLPADDING="1" CELLSPACING="0" BORDER="0" ALIGN="CENTER">
  2382.   <TR>
  2383.     <TD VALIGN="TOP">
  2384.       <TABLE BGCOLOR="$headingcolor" WIDTH="100%" CELLPADDING="2" CELLSPACING="1" BORDER="0">
  2385.         <TR ALIGN="LEFT">
  2386.           <TD><B><FONT SIZE="2">
  2387.           <PRE>
  2388. $_</PRE>
  2389.           </TD>
  2390.         </TR>
  2391.       </TABLE>
  2392.     </TD>
  2393.   </TR>
  2394. </TABLE>
  2395. EOF
  2396. # Check to see if it is a select statement.
  2397.       if (/^SELECT/i) {
  2398.          $text = "";
  2399.          $link="";
  2400.          $infotext = "No rows to display.";
  2401.          $error = DisplayTable($_,$text,$link,$infotext);
  2402.          logit("   DisplayTable returned $error") if $error;
  2403.          unless ($error =~ /^d+$/) {
  2404.             message("Select statement failed: $errorn");
  2405.          }
  2406.          print "<BR>n";
  2407. # If not a select, then "do" the statement
  2408.       } else {
  2409.          $cursor=$dbh->do($_);
  2410.          if ( ! $cursor) {
  2411.             $_ = $DBI::errstr;
  2412. # Get rid of unneccessary DBD::Oracle message
  2413.             s/DBD: //;
  2414.             s/(DBD.*)//;
  2415.             message("SQL error:<BR>$_n");
  2416.          } else {
  2417.             message("SQL statement executed successfully.n");
  2418.             $rows = $dbh->rows;
  2419.             if ($rows > 0) {
  2420.                message("$rows rows affected.n");
  2421.             }
  2422.             Footer();
  2423.          }
  2424.       }
  2425.    print "<HR WIDTH="10%">n";
  2426.    }
  2427.    logit("Exit subroutine runSQL");
  2428. }
  2429. sub runExplainPlan {
  2430.    logit("Enter subroutine runExplainPlan");
  2431.    my ($sql,$cursor,$count,$text,$link,$infotext,@row,$title,$heading,$explainsql,$rc);
  2432.    my ($utlxplan733,$utlxplan8,$operation,$options,$objname,$cost,$table_color,$foo);
  2433.    my ($objtype,$objowner,$card,$bytes,$other,$maxlength,$line,$numspaces,$i,$linelength);
  2434.    my ($optimizer);
  2435. $utlxplan733 = "
  2436. create table PLAN_TABLE (
  2437.         statement_id    varchar2(30),
  2438.         timestamp       date,
  2439.         remarks         varchar2(80),
  2440.         operation       varchar2(30),
  2441.         options         varchar2(30),
  2442.         object_node     varchar2(128),
  2443.         object_owner    varchar2(30),
  2444.         object_name     varchar2(30),
  2445.         object_instance numeric,
  2446.         object_type     varchar2(30),
  2447.         optimizer       varchar2(255),
  2448.         search_columns  numeric,
  2449.         id              numeric,
  2450.         parent_id       numeric,
  2451.         position        numeric,
  2452.         cost            numeric,
  2453.         cardinality     numeric,
  2454.         bytes           numeric,
  2455.         other_tag       varchar2(255),
  2456.         other           long)
  2457. ";
  2458. $utlxplan8 = "
  2459. create table PLAN_TABLE (
  2460.         statement_id    varchar2(30),
  2461.         timestamp       date,
  2462.         remarks         varchar2(80),
  2463.         operation       varchar2(30),
  2464.         options         varchar2(30),
  2465.         object_node     varchar2(128),
  2466.         object_owner    varchar2(30),
  2467.         object_name     varchar2(30),
  2468.         object_instance numeric,
  2469.         object_type     varchar2(30),
  2470.         optimizer       varchar2(255),
  2471.         search_columns  number,
  2472.         id              numeric,
  2473.         parent_id       numeric,
  2474.         position        numeric,
  2475.         cost            numeric,
  2476.         cardinality     numeric,
  2477.         bytes           numeric,
  2478.         other_tag       varchar2(255),
  2479.         partition_start varchar2(255),
  2480.         partition_stop  varchar2(255),
  2481.         partition_id    numeric,
  2482.         other           long)
  2483. ";
  2484. # Connect to database using ID of the owner of the SQL passed. This will 
  2485. # actually mean that the Oracletool that created the menu is (was) connected
  2486. # as the user with "SELECT ANY TABLE" privileges while the connection in 
  2487. # the body does not need that level of access. Therefore, any clicks on the
  2488. # menu buttons will reconnect as the main user, not the SQL owner. Yeah, whatever.
  2489. # Have I mentioned that CGI bites?
  2490.    my $data_source = "dbi:Oracle:$database";
  2491.    my $dbh = DBI->connect($data_source,$explainschema,$password,{PrintError=>0});
  2492.    if (! $dbh) {
  2493.       $object_name =~ s/"/&quot;/g;
  2494.       $object_name =~ s/>/&gt;/g;
  2495.       $object_name =~ s/</&lt;/g;
  2496.       if ($explainschema) {
  2497.          ErrorPage("Could not connect as $explainschema.<BR>$DBI::errstr");
  2498.          exit;
  2499.       } else {
  2500.          ErrorPage("Please enter a username and password.");
  2501.          exit;
  2502.       }
  2503.    }
  2504. # OK, we're connected, let's display the header.
  2505.    Header($title,$heading,$font,$fontsize,$fontcolor,$bgcolor);
  2506. # Now, check for a plan table under this schema.
  2507.    $sql = "$copyright
  2508. SELECT COUNT(*)
  2509.    FROM USER_TABLES
  2510. WHERE TABLE_NAME = 'PLAN_TABLE'
  2511. ";
  2512.    $cursor=$dbh->prepare($sql);
  2513.    $cursor->execute;
  2514.    $count = $cursor->fetchrow_array;
  2515.    $cursor->finish;
  2516.    if (! $count) {
  2517. # No plan table exists. Let's create one.
  2518.       if (! $oracle8) {
  2519.          $sql = $utlxplan733;
  2520.       } else {
  2521.          $sql = $utlxplan8;
  2522.       }
  2523.       $cursor = $dbh->do($sql);
  2524.       if (! $cursor) {
  2525.          message("Could not create PLAN_TABLE.<BR>$DBI::errstrn");
  2526.          $dbh->disconnect;
  2527.          exit;
  2528.       }
  2529.       message("$explainschema did not have a PLAN_TABLE required for explain plan. Oracletool has created this table for you.");
  2530.    }
  2531. # Got a connection, and a PLAN_TABLE exists.
  2532. # Set the statement_id to a unique identifier.
  2533.    $statement_id = "Oracletool.$$";
  2534.    $explainsql = $object_name;
  2535. # Get rid of ;, if one exists
  2536.    $explainsql =~ s/;$//;
  2537.    $explainsql = "EXPLAIN PLAN SET STATEMENT_ID = '$statement_id' INTO PLAN_TABLE FOR $explainsql";
  2538.    $cursor=$dbh->do($explainsql);
  2539.    if ( ! $cursor) { 
  2540.       message("Could not execute explain plan.<BR>$DBI::errstrn");
  2541.    } else {
  2542.       text("Explain plan executed successfully.n");
  2543.    }
  2544.    $sql = "$copyright
  2545. SELECT
  2546.    DISTINCT OPTIMIZER
  2547. FROM PLAN_TABLE
  2548.    WHERE STATEMENT_ID = '$statement_id'
  2549. ";
  2550.    $cursor = $dbh->prepare($sql);
  2551.    $cursor->execute;
  2552.    $optimizer = $cursor->fetchrow_array;
  2553.    $cursor->finish;
  2554.    text("Optimizer mode is $optimizer.");
  2555.    $sql = "$copyright
  2556. SELECT 
  2557.    LPAD(' ',2*LEVEL-1)||OPERATION ,
  2558.    OPTIONS,
  2559.    OBJECT_NAME,
  2560.    OBJECT_TYPE,
  2561.    OBJECT_OWNER,
  2562.    COST,
  2563.    CARDINALITY,
  2564.    BYTES,
  2565.    OTHER_TAG
  2566. FROM PLAN_TABLE
  2567. START WITH ID=0 
  2568.    AND STATEMENT_ID = '$statement_id'
  2569. CONNECT BY PRIOR ID = PARENT_ID 
  2570.    AND STATEMENT_ID = '$statement_id'
  2571. ORDER BY ID
  2572. ";
  2573.    $cursor=$dbh->prepare($sql);
  2574.    $cursor->execute;
  2575.    $maxlength = 0;
  2576.    while (($operation,$options,$objname,$objtype,$objowner,$cost,$card,$bytes,$other) = $cursor->fetchrow_array) {
  2577.       $line = "$operation $options $objname";
  2578.       if ($cost) {
  2579.          $line .= "Cost: $cost "; 
  2580.       }
  2581.       if (length($line) > $maxlength) {
  2582.          $maxlength = length($line);
  2583.          logit("   Explain plan max line length is $maxlength");
  2584.       }
  2585.    }
  2586.    $cursor->finish;   
  2587.    print "<TABLE BORDER=0 BGCOLOR=$table_color>n";
  2588.    $cursor=$dbh->prepare($sql);
  2589.    $cursor->execute;
  2590.    while (($operation,$options,$objname,$objtype,$objowner,$cost,$card,$bytes,$other) = $cursor->fetchrow_array) {
  2591.       logit("   Explain: $operation,$options,$objname,$objtype,$objowner,$cost,$card,$bytes,$other");
  2592.       if ($foo) {
  2593.          $table_color = "#C6EFF7";
  2594.          $foo--;
  2595.       } else {
  2596.          $table_color = "#DEBDDE";
  2597.          $foo++
  2598.       }
  2599.       $linelength = length("$operation $options $other $objname");
  2600.          print "<TR BGCOLOR=$table_color><TD><FONT COLOR='$fontcolor' SIZE='$fontsize' FACE='$font'><PRE><B>$operation $options $other ";
  2601.       if ($objowner) {
  2602.          print "$objowner.$objname";
  2603.        } else {
  2604.          print "$objname";
  2605.      }
  2606.       if ($cost) {
  2607.          $numspaces = $maxlength-$linelength+5;
  2608.          for($i = 0; $i <= $numspaces; $i++) {
  2609.            print " ";
  2610.          } 
  2611.          print "Cardinality: $card " if $card;
  2612.          print "Cost: $cost " if $cost;
  2613.       }
  2614.       print "</TD></TR>n";
  2615.       $cost = 0;
  2616.    }
  2617.    $cursor->finish;
  2618.    print "</TABLE>n";
  2619.    $sql = "$copyright
  2620. DELETE FROM PLAN_TABLE 
  2621.    WHERE STATEMENT_ID = '$statement_id'
  2622. ";
  2623.    $rc = $dbh->do($sql);
  2624.    unless ($rc) {
  2625.       $dbh->disconnect;
  2626.       ErrorPage("Could not delete records from PLAN_TABLE");
  2627.    }
  2628.    $dbh->disconnect;
  2629.    Footer();
  2630.    logit("Exit subroutine runExplainPlan");
  2631.    exit;
  2632. }
  2633. sub enterWorksheet {
  2634.    logit("Enter subroutine enterWorksheet");
  2635.    my ($sql);
  2636.    message("Connected to $database as $schema.");
  2637.    text("Enter or paste the SQL you wish to execute.<BR>Terminate statements with a <B>';'</B> if entering multiple statements.");
  2638.    print <<"EOF";
  2639. <FORM>
  2640. <FONT COLOR='$fontcolor' SIZE='$fontsize' FACE='$font'>
  2641. <INPUT TYPE=HIDDEN NAME=object_type VALUE=RUNSQL>
  2642. <INPUT TYPE=HIDDEN NAME=database VALUE=$database>
  2643. <INPUT TYPE=HIDDEN NAME=schema VALUE=$schema>
  2644. <TEXTAREA NAME=arg ROWS=$textarea_h COLS=$textarea_w></TEXTAREA>
  2645. <P>
  2646. </B>
  2647. <INPUT TYPE=SUBMIT VALUE="Execute">
  2648. </FORM>
  2649. EOF
  2650.    logit("Exit subroutine enterWorksheet");
  2651. }
  2652. sub sqlAreaList {
  2653.    logit("Enter subroutine sqlAreaList");
  2654.    my ($sql,$text,$link,$infotext);
  2655.    $sql = "$copyright
  2656. SELECT
  2657.    DU.USERNAME                  "Username",
  2658.    COUNT(SQL_TEXT)              "# Entries"
  2659. FROM DBA_USERS DU, V$SQL VSA
  2660.    WHERE DU.USER_ID = VSA.PARSING_SCHEMA_ID
  2661. GROUP BY USERNAME,PARSING_SCHEMA_ID
  2662. ORDER BY 2 DESC
  2663. ";
  2664.    $text = "The following users have SQL in the shared SQL area. Choose a user to display the parsed SQL.";
  2665.    $link = "$scriptname?database=$database&object_type=SQLAREALISTBYUSER";
  2666.    $infotext = "There are no entries in the shared SQL area";
  2667.    DisplayTable($sql,$text,$link,$infotext);
  2668.    logit("Exit subroutine sqlAreaList");
  2669. }
  2670. sub sqlAreaListByUser {
  2671.    logit("Enter subroutine sqlAreaListByUser");
  2672.    my ($sql,$cursor,$text,$link,$infotext);
  2673.    $sql = "$copyright
  2674. SELECT
  2675.    TO_CHAR(EXECUTIONS,'999,999,999,999') "Executions",
  2676.    TO_CHAR(ROWS_PROCESSED,'999,999,999,999') "Rows processed",
  2677.    TO_CHAR(DISK_READS,'999,999,999,999') "Disk reads",
  2678.    TO_CHAR(SORTS,'999,999,999,999') "Sorts",
  2679.    OPTIMIZER_MODE "Optimizer mode",
  2680.    SQL_TEXT "SQL text"
  2681. FROM V$SQL
  2682.    WHERE PARSING_SCHEMA_ID = 
  2683. (SELECT USER_ID FROM DBA_USERS 
  2684.    WHERE USERNAME = '$object_name')
  2685. ORDER BY 1 DESC, 2 DESC, 3 DESC, 4 DESC
  2686. ";
  2687.    logit($sql);
  2688.    $text = " SQL for user $object_name in the shared SQL area.";
  2689.    $link = "";
  2690.    $infotext = "There are no entries in the shared SQL area for user $object_name";
  2691.    DisplayTable($sql,$text,$link,$infotext);
  2692.    logit("Exit subroutine sqlAreaListByUser");
  2693. }
  2694. sub enterExplainPlan {
  2695.    logit("Enter subroutine enterExplainPlan");
  2696.    my ($sql,$cursor,$count,$text,$link,$infotext);
  2697.    my ($owner,$table_name,$title,$heading);
  2698.    Header($title,$heading,$font,$fontsize,$fontcolor,$bgcolor);
  2699.    if ($explainschema) {
  2700. print <<"EOF";
  2701. SQL belongs to user $explainschema<BR>
  2702. Edit SQL and proceed
  2703. <FORM METHOD="POST" ACTION="$scriptname">
  2704.   <FONT COLOR='$fontcolor' SIZE='$fontsize' FACE='$font'>
  2705.   <INPUT TYPE=HIDDEN NAME=object_type VALUE=RUNEXPLAINPLAN>
  2706.   <INPUT TYPE=HIDDEN NAME=database VALUE=$database>
  2707.   <INPUT TYPE=HIDDEN NAME=explainschema VALUE=$explainschema>
  2708.   <TEXTAREA NAME=arg ROWS=$textarea_h COLS=$textarea_w WRAP=SOFT>$object_name</TEXTAREA>
  2709. <P>Enter password for user $explainschema<P>
  2710.   <INPUT TYPE=PASSWORD NAME=password SIZE=20>
  2711.   <INPUT TYPE="SUBMIT" NAME="foobar" VALUE="Run explain plan">
  2712. </FORM>
  2713. EOF
  2714.    } else {
  2715.       print <<"EOF";
  2716. Enter SQL below
  2717. <FORM METHOD="POST" ACTION="$scriptname">
  2718.   <FONT COLOR='$fontcolor' SIZE='$fontsize' FACE='$font'>
  2719.   <INPUT TYPE=HIDDEN NAME=object_type VALUE=RUNEXPLAINPLAN>
  2720.   <INPUT TYPE=HIDDEN NAME=database VALUE=$database>
  2721.   <FONT FACE="$font" SIZE="$fontsize">
  2722.   <TEXTAREA NAME=arg ROWS=$textarea_h COLS=$textarea_w WRAP=SOFT>$object_name</TEXTAREA>
  2723.   <TABLE BORDER=0>
  2724.     <TR>
  2725.       <TD ALIGN=CENTER>
  2726.         <FONT FACE="$font" SIZE="$fontsize" COLOR="$fontcolor">
  2727.         Enter user to run SQL<BR>
  2728.           <INPUT TYPE=TEXT NAME=explainschema SIZE=20 MAXLENGTH=40>
  2729.       </TD>
  2730.       <TD ALIGN=CENTER>
  2731.         <FONT FACE="$font" SIZE="$fontsize" COLOR="$fontcolor">
  2732.         Enter password for user<BR>
  2733.           <INPUT TYPE=PASSWORD NAME=password SIZE=20>
  2734.       </TD>
  2735.     </TR>
  2736.   </TABLE>
  2737.   <BR>
  2738.   <INPUT TYPE="SUBMIT" NAME="foobar" VALUE="Run explain plan">
  2739. </FORM>
  2740. EOF
  2741.    }
  2742.    logit("Exit subroutine enterExplainPlan");
  2743. exit;
  2744. }
  2745. sub showDBfiles {
  2746.    logit("Enter subroutine showDBfiles");
  2747.    my ($sql,$text,$link,$infotext);
  2748. print <<"EOF";
  2749. <TABLE BORDER=0 CELLPADDING=0 CELLSPACING=0>
  2750.   <TR>
  2751.     <TD ALIGMN=CENTER>
  2752.       <FORM METHOD="GET" ACTION="$scriptname">
  2753.         <FONT COLOR='$fontcolor' SIZE='$fontsize' FACE='$font'>
  2754.         <INPUT TYPE="HIDDEN" NAME="database" VALUE="$database">
  2755.         <INPUT TYPE="HIDDEN" NAME="object_type" VALUE="FILEGRAPH">
  2756.         <INPUT TYPE="SUBMIT" NAME="filegraph" VALUE="Datafile graph by file I/O">
  2757.       </FORM>
  2758.     </TD>
  2759.   </TR>
  2760. </TABLE>
  2761. EOF
  2762. # Show any files that need media recovery.
  2763.    $sql = "$copyright
  2764. SELECT 
  2765.    A.FILE_NAME "File name",
  2766.    A.TABLESPACE_NAME "Tablespace name",
  2767.    A.FILE_ID "File#",
  2768.    A.STATUS "Status",
  2769.    B.ERROR "Error",
  2770.    B.CHANGE# "Start SCN",
  2771.    TO_CHAR(B.TIME,'Month DD, YYYY - HH24:MI:SS') "Recover from.."
  2772. FROM DBA_DATA_FILES A,
  2773.      V$RECOVER_FILE B
  2774. WHERE A.FILE_ID = B.FILE#
  2775. ";
  2776.    $text = "Datafiles need recovery!!";
  2777.    $link = "$scriptname?database=$database&object_type=DATAFILE";
  2778.    $infotext = "No datafiles are needing media recovery :-)";
  2779.    DisplayTable($sql,$text,$link,$infotext);
  2780.    $sql = "$copyright
  2781. SELECT
  2782.    TO_CHAR(SUM(BYTES),'999,999,999,999,999')    "Total allocated space"
  2783. FROM DBA_DATA_FILES
  2784. ";
  2785.    $text = "";
  2786.    $link = "";
  2787.    DisplayTable($sql,$text,$link);
  2788. # General datafile information, all datafiles
  2789.    if ($oracle8) {
  2790.       $sql = "$copyright
  2791. SELECT
  2792.    A.FILE_NAME "File name",
  2793.    TO_CHAR(A.BYTES,'999,999,999,999') "Bytes",
  2794.    A.TABLESPACE_NAME "Tablespace_name",
  2795.    TO_CHAR(B.PHYBLKRD,'999,999,999,999') "Physical block reads",
  2796.    TO_CHAR(B.PHYBLKWRT,'999,999,999,999') "Physical block writes",
  2797.    A.STATUS "Status",
  2798.    DECODE(A.AUTOEXTENSIBLE,
  2799.                            'YES','Yes',
  2800.                            'NO','No') "Xtend?",
  2801.    TO_CHAR(A.MAXBYTES,'999,999,999,999') "Max bytes",
  2802.    TO_CHAR(A.INCREMENT_BY*$db_block_size,'999,999,999,999') "Increment"
  2803. FROM DBA_DATA_FILES A, V$FILESTAT B
  2804.    WHERE A.FILE_ID = B.FILE#
  2805. ORDER BY A.FILE_NAME, A.TABLESPACE_NAME
  2806. ";
  2807.    } else {
  2808.       $sql = "$copyright
  2809. SELECT
  2810.    A.FILE_NAME "File name",
  2811.    TO_CHAR(A.BYTES,'999,999,999,999') "Bytes",
  2812.    A.TABLESPACE_NAME "Tablespace_name",
  2813.    TO_CHAR(B.PHYBLKRD,'999,999,999,999') "Physical block reads",
  2814.    TO_CHAR(B.PHYBLKWRT,'999,999,999,999') "Physical block writes",
  2815.    A.STATUS "Status"
  2816. FROM DBA_DATA_FILES A, V$FILESTAT B
  2817.    WHERE A.FILE_ID = B.FILE#
  2818. ORDER BY A.FILE_NAME, A.TABLESPACE_NAME
  2819. ";
  2820.    }
  2821.    $text = "Datafile information: Database $database";
  2822.    $link = "$scriptname?database=$database&object_type=DATAFILE";
  2823.    DisplayTable($sql,$text,$link);
  2824.    logit("Exit subroutine showDBfiles");
  2825. }
  2826. sub EnterPasswd {
  2827.    logit("Enter subroutine EnterPasswd");
  2828. # Usage: EnterPasswd($database);
  2829.    if ($object_type ne "MENU") {
  2830.    my $database      = shift;
  2831.    my ($title,$heading);
  2832.    $title = "Add database $database";
  2833.    $heading = "Please enter a username and password for database $database.<BR>This user needs to have CREATE SESSION and SELECT ANY TABLE privileges.";
  2834.    Header($title,$heading,$font,$fontsize,$fontcolor,$bgcolor);
  2835.    print <<"EOF";
  2836. </CENTER>
  2837.   <P>
  2838.     <TABLE BGCOLOR="BLACK" WIDTH="400" CELLPADDING="1" CELLSPACING="0" BORDER="0">
  2839.       <TR>
  2840.         <TD VALIGN="TOP">
  2841.           <TABLE BGCOLOR="$headingcolor" WIDTH="100%" CELLPADDING="2" CELLSPACING="1" BORDER="0">
  2842.             <TR ALIGN="CENTER">
  2843.               <TD ALIGN=LEFT>
  2844.                 <FORM METHOD="POST" ACTION="$scriptname">
  2845.                 <FONT COLOR='$fontcolor' SIZE='$fontsize' FACE='$font'>
  2846.                 <BR><STRONG>&nbsp;&nbsp;&nbsp;Enter the username</STRONG>
  2847.                 <P>
  2848.                 <INPUT TYPE="TEXT" SIZE="20" NAME="username" MAXLENGTH="20">
  2849.                 <P>
  2850.                 <STRONG>&nbsp;&nbsp;&nbsp;Enter the password</STRONG>
  2851.                 <P>
  2852.                 <INPUT TYPE="PASSWORD" SIZE="20" NAME="password" MAXLENGTH="20">
  2853.                 <P>
  2854.                 <INPUT TYPE="HIDDEN" NAME="object_type" VALUE="ADDPASSWORD">
  2855.                 <INPUT TYPE="HIDDEN" NAME="database" VALUE="$database">
  2856.                 &nbsp;&nbsp;&nbsp;<INPUT TYPE="SUBMIT" VALUE="Submit">
  2857.                 </FORM>
  2858.               </TD>
  2859.             </TR>
  2860.           </TABLE>
  2861.         </TD>
  2862.       </TR>
  2863.     </TABLE>
  2864. EOF
  2865.    logit("Exit subroutine EnterPasswd");
  2866. exit;
  2867.     } else {
  2868.       Header($title,$heading,$font,$fontsize,$fontcolor,$bgcolor);
  2869.    }
  2870.    logit("Exit subroutine EnterPasswd");
  2871. }
  2872. sub GetPasswd {
  2873.    logit("Enter subroutine GetPasswd");
  2874. # Usage: $info = GetPasswd($database);
  2875.    my $database      = shift;
  2876.    my ($sessionid,$username,$password,$usercookie,$passcookie,$info,$message,$duration,$url,$path);
  2877.    my ($sessioncookie,$bgline);
  2878. #   if ($encryption_string) {
  2879. #      logit("   Encryption string = $encryption_string");
  2880. #    } else {
  2881. #      logit("   Encryption string is not set");
  2882. #   }
  2883.    if ( defined $expire ) {
  2884.       logit("   Expiring password cookie");
  2885.       $path = dirname($scriptname);
  2886.       $sessionid = "undefined";
  2887.       $sessioncookie = cookie(-name=>"$database.sessionid",-value=>"$sessionid",-expires=>"-1y",-path=>"$path");
  2888.       print header(-cookie=>$sessioncookie);
  2889.       $message     = "Password cookie for database $database has been expired.";
  2890.       $duration    = "1";
  2891.       $url         = "$scriptname";
  2892.       $bgline = "<BODY BGCOLOR=$bgcolor>n";
  2893.       if ($bgimage) {
  2894.          if ((-e "$ENV{'DOCUMENT_ROOT'}/$bgimage") && (-r "$ENV{'DOCUMENT_ROOT'}/$bgimage")) {
  2895.             logit("   Background image is $ENV{'DOCUMENT_ROOT'}/$bgimage and is readable");
  2896.             $bgline = "<BODY BACKGROUND=$bgimage>n";
  2897.          }
  2898.       }
  2899.       print <<"EOF";
  2900. <HTML>
  2901.   <HEAD>
  2902.     <TITLE>Notice!</TITLE>
  2903.     <META HTTP-EQUIV="Refresh" Content="$duration;URL=$url">
  2904.   </HEAD>
  2905.     $bgline
  2906.     <FONT FACE="$font" SIZE="$fontsize" COLOR="$fontcolor">
  2907.     <CENTER>
  2908.       $message
  2909.     </CENTER
  2910.   </BODY
  2911. </HTML>
  2912. EOF
  2913.       logit("Exit subroutine GetPasswd");
  2914.       exit;
  2915.     }
  2916.    $sessionid = cookie("$database.sessionid");
  2917.    ($username,$password) = decodeSessionid($sessionid);
  2918.    $info = "$username $password";
  2919.    logit("Exit subroutine GetPasswd");
  2920.    return($info);
  2921. }
  2922. sub encryptionEnabled {
  2923.    logit("Enter sub encryptionEnabled");
  2924.    my $digest_found = (eval "require MD5");
  2925.    my $crypt_found = (eval "require Crypt::CBC");
  2926.    my $idea_found = (eval "require Crypt::IDEA");
  2927.    my $mime_found = (eval "require MIME::Base64");
  2928. # We need Digest::MD5 for any type of encryption, so check for 
  2929. # this first.
  2930.    if ($digest_found) {
  2931.       logit("   Digest::MD5 is installed. Good");
  2932. # Check for both Crypt::CBC and Crypt::IDEA for encryption level 2.
  2933.       if ($crypt_found && $idea_found) {
  2934.          logit("   Crypt::CBC is installed. Good.");
  2935.          logit("   Crypt::IDEA is installed. Good.");
  2936.          $encryption_enabled = 2;
  2937.        } else {
  2938.          logit("   Crypt::CBC is not installed!");
  2939.          logit("      -- or --  ");
  2940.          logit("   Crypt::IDEA is not installed!");
  2941.          logit("   Checking for MIME::Base64 instead.");
  2942.          if ($mime_found) {
  2943.             logit("   MIME::Base64 is installed. Good.");
  2944.             $encryption_enabled = 1;
  2945.          }
  2946.       }
  2947.    } else {
  2948.       logit("   Digest::MD5 is not installed. Encryption disabled!");
  2949.    }
  2950.    logit("   Value for encryption_enabled is $encryption_enabled");
  2951.    if ($encryption_enabled) {
  2952.       if ($encryption_string eq "changeme") {
  2953.          logit("   Encryption key is set to the default! Change it!");
  2954.        } else {
  2955.          logit("   Encryption key is non-default. Good.");
  2956.       }
  2957.    }
  2958.    logit("Exit sub encryptionEnabled");
  2959. }
  2960. sub buildSessionid {
  2961.    logit("Enter sub buildSessionid");
  2962.    my ($username,$password) = @_;
  2963.    
  2964.    my $sessionid;
  2965. # $encryption enabled will be 0 if no encryption modules are installed.
  2966. # $encryption enabled will be 1 if Digest::MD5 is installed,
  2967. # but Crypt::CBC _and_ CRYPT::IDEA are not.
  2968. # $encryption enabled will be 3 if all three modules are installed.
  2969.    if ($encryption_enabled) {
  2970.       logit("   Encryption enabled, attempting to encrypt username / password.");
  2971.       if ($encryption_enabled == 1) {
  2972.          logit("   Digest::MD5 encryption only.");
  2973.          $sessionid = encodeLevel1($username,$password);
  2974.       }
  2975.       if ($encryption_enabled == 2) {
  2976.          logit("   Full IDEA encryption.");
  2977.          $sessionid = encodeLevel2($username,$password);
  2978.       }
  2979.       if ($sessionid) {
  2980.          logit("   Encrypt was successful.");
  2981.        } else {
  2982.          logit("   Encrypt was not successful!");
  2983.       }
  2984.     } else {
  2985.       logit("   Encryption not enabled, attempting to build unencrypted sessionid.");
  2986.       ($sessionid) = "$username~$password";
  2987.       if ($sessionid) {
  2988.          logit("   Build was successful.");
  2989.        } else {
  2990.          logit("   Build was not successful!");
  2991.       }
  2992.    }
  2993.    logit("Exit sub buildSessionid");
  2994.    return($sessionid);
  2995. }
  2996. sub encodeLevel1 {
  2997.    logit("Enter sub encodeLevel1");
  2998.    my ($username,$password) = @_;
  2999.    my ($sessionid,$context,$checksum);
  3000.    $context = new MD5;
  3001.    $context->add($username,$password,$encryption_string);
  3002.    $checksum = $context->digest();
  3003.    $sessionid=join("-",
  3004.       map { MIME::Base64::encode($_) }
  3005.       ($username,$password,$checksum));
  3006.    $sessionid=~s|n||g;
  3007.    return($sessionid);
  3008.    logit("Exit sub encodeLevel1");
  3009. }
  3010. sub encodeLevel2 {
  3011.    logit("Enter sub encodeLevel2");
  3012.    my ($username,$password) = @_;
  3013.    my $sessionid;
  3014.    $sessionid = Crypt::CBC->new($encryption_string,'IDEA')->
  3015.    encrypt_hex(join("",($username,$password)));
  3016.    logit("Exit sub encodeLevel2");
  3017.    return($sessionid);
  3018.    
  3019. }
  3020. sub decodeLevel1 {
  3021.    logit("Enter sub decodeLevel1");
  3022.    my $sessionid = shift;
  3023.    my ($username,$password,$context,$checksum,$new_checksum);
  3024.    ($username,$password,$checksum) =
  3025.       map { MIME::Base64::decode($_) } split(/-/,$sessionid);
  3026.    $context = new MD5;
  3027.    $context->add($username,$password,$encryption_string);
  3028.    $new_checksum = $context->digest();
  3029.    if ( $checksum ne $new_checksum ) { 
  3030.       logit("   WARNING: The encryption string has been tampered with or changed.");
  3031.       $username = "$new_checksum";
  3032.       $password = "$new_checksum";
  3033.    }
  3034.    logit("Exit sub decodeLevel1");
  3035.    return ($username,$password);
  3036. }
  3037. sub decodeLevel2 {
  3038.    logit("Enter sub decodeLevel2");
  3039.    my $sessionid = shift;
  3040.    my ($username,$password);
  3041.    ($username,$password) = split(//, Crypt::CBC->new($encryption_string,'IDEA')->
  3042.    decrypt_hex($sessionid));
  3043.    return($username,$password); 
  3044.    logit("Exit sub decodeLevel2");
  3045. }
  3046. sub decodeSessionid {
  3047.    logit("Enter sub decodeSessionid");
  3048.    my($sessionid) = shift;
  3049.    my ($username,$password);
  3050.    if ($encryption_enabled) {   
  3051.       if ($encryption_enabled == 1) {
  3052.          logit("   Encryption enabled (1), attempting to decrypt username / password.");
  3053.          ($username,$password) = decodeLevel1($sessionid);
  3054.       }
  3055.       if ($encryption_enabled == 2) {
  3056.          logit("   Encryption enabled(2), attempting to decrypt username / password.");
  3057.          ($username,$password) = decodeLevel2($sessionid);
  3058.       }
  3059.       if ($username && $password) {
  3060.          logit("   Decrypt was successful.");
  3061.        } else {
  3062.          logit("   Decrypt was not successful!");
  3063.       }
  3064.     } else {
  3065.       logit("   Encryption not enabled, attempting to split username / password.");
  3066.       ($username,$password) = split(/~/, $sessionid);
  3067.       if ($username && $password) {
  3068.          logit("   Split was successful.");
  3069.        } else {
  3070.          logit("   Split was not successful!");
  3071.       }
  3072.    }
  3073.    logit("Exit sub decodeSessionid");
  3074.    return ($username,$password);
  3075. }
  3076. sub addPasswd {
  3077.    logit("Enter subroutine addPasswd");
  3078.    my $database = shift;
  3079.    my $username = shift;
  3080.    my $password = shift;
  3081.    my ($sql,$cursor,$count,$message,$duration,$url,$usercookie,$passcookie);
  3082.    my ($role,@allroles,$foo,$dbstatus,$sessionid,$sessioncookie,$bgline);
  3083. # Connect to the database.
  3084.    $dbh = dbConnect($database,$username,$password);
  3085. # Determine the database status. (OPEN,MOUNTED etc.)
  3086.    $dbstatus = dbStatus();
  3087.    if ($dbstatus eq "OPEN") {
  3088. # First, check to be sure this user has "SELECT ANY TABLE" privilege.
  3089. # If not, send them packing.
  3090.       $count = checkPriv("SELECT ANY TABLE");
  3091.       if ($count < 1) {
  3092.          ErrorPage("The username you have specified does not have the appropriate permissions to use this tool. Please specify a username with SELECT ANY TABLE privileges.");
  3093.       }
  3094.       $dbh->disconnect;
  3095.    }