mm_sql.c revision d1d2228c6cf3ec632d28262810ab7902932a5d33
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*
* Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <syslog.h>
#include <mms_list.h>
#include <mms_parser.h>
#include <mms_par_impl.h>
#include <libpq-fe.h>
#include <mms_trace.h>
#include <mms_strapp.h>
#include <pthread.h>
#include "mm_db.h"
#include "mm.h"
#include "mm_util.h"
#include "mm_commands.h"
#include "mm_sql.h"
#include "mm_sql_impl.h"
#include "mm_path.h"
static sql_ops_tab_t opstab[] = {
"strlohi", "ASC",
"strhilo", "DESC",
"numlohi", "ASC",
"numhilo", "DESC",
"regex", "~",
"streq", "=",
"strne", "<>",
"strlt", "<",
"strle", "<=",
"strgt", ">",
"strge", ">=",
"numeq", "=",
"numne", "<>",
"numlt", "<",
"numle", "<=",
"numgt", ">",
"numge", ">=",
"and", "AND",
"or", "OR",
"not", "NOT",
"hosteq", "=",
"hostne", "<>"
};
char *
{
char *value;
char *cart_pcl;
/*
* Get cartridge pcl from cartridge id
*/
return (NULL);
}
return (NULL);
}
return (NULL);
}
if (value[0] == '\0') {
value = "none";
}
}
return (cart_pcl);
}
int
return (1);
}
/* Allowed values for status are : */
/* in use */
/* unavailable */
/* available */
"update \"CARTRIDGE\" "
"set \"CartridgeStatus\" = '%s' "
"where \"CartridgeID\" = '%s';",
"Error updateing cartridge state, %s, %s",
return (1);
}
return (0);
}
int
return (1);
}
/* Allowed values for status are : */
/* in use */
/* ready */
"update \"DRIVE\" "
"set \"DriveStateSoft\" = '%s' "
"where \"DriveName\" = '%s';",
"Error updateing drive state, %s, %s",
return (1);
}
return (0);
}
void
mm_set_mount_info_cart(char *cart_id,
if (mount_info->cmi_cartridge)
cart_id);
}
void
mm_set_mount_info_drive(char *drive,
if (mount_info->cmi_drive)
drive);
}
void
mm_set_mount_info_library(char *library,
if (mount_info->cmi_library)
library);
}
void
mm_set_mount_info_dm(char *dm,
if (mount_info->cmi_dm)
mount_info->cmi_dm =
dm);
}
void
mm_set_mount_info_pcl(char *pcl,
if (mount_info->cmi_pcl)
pcl);
}
void
if (mount_info->cmi_cartridge)
if (mount_info->cmi_drive)
if (mount_info->cmi_library)
if (mount_info->cmi_dm)
if (mount_info->cmi_pcl)
}
void
"DM, %s, Status for Drive, %s, host, %s",
" DMStateHard = %s",
" DMStateSoft = %s",
" DMDisabled = %s",
}
void
return;
}
if (dm_stat->dm_stat_name)
if (dm_stat->dm_stat_hard)
if (dm_stat->dm_stat_disabled)
if (dm_stat->dm_stat_soft)
if (dm_stat->dm_stat_host)
if (dm_stat->dm_stat_drive)
}
/* when dm name is null, use drive and host to return the dm status */
"select "
"\"DM\".\"DMStateHard\", "
"\"DM\".\"DMStateSoft\", "
"\"DM\".\"DriveName\", "
"\"DM\".\"DMDisabled\", "
"\"DM\".\"DMTargetHost\", "
"\"DM\".\"DMName\" "
"from \"DM\" ");
if ((drive_name == NULL) ||
"need drive and host if dm namd is null",
", mm_get_dm_status");
return (NULL);
}
"where \"DriveName\" = '%s' "
"and pg_host_ident(\"DMTargetHost\") "
"= pg_host_ident('%s');",
host);
} else {
/* use dm name constrant */
"where \"DM\".\"DMName\" = '%s'",
dm_name);
}
"db error, mm_get_dm_status");
return (NULL);
}
"row num mismatch, "
"mm_get_drive_status");
return (NULL);
}
"Unable to malloc dm_status");
return (NULL);
}
return (dm_status);
}
void
"Drive Status for Drive, %s",
" DriveDisabled = %s",
" DriveBroken = %s",
" DriveStateSoft = %s",
" DriveStateHard = %s",
" DriveLibraryAccessible = %s",
" ExclusiveAppName = %s",
" DriveOnline = %s",
" DriveGroupName = %s",
" LibraryName = %s",
" DrivePriority = %s",
" DMName = %s",
" DriveGeometry = %s",
" DriveSerialNum = %s",
" CartridgePCL = %s",
" DriveLibraryOccupied = %s",
}
void
if (drive_stat == NULL) {
return;
}
if (drive_stat->drive_stat_name)
if (drive_stat->drive_stat_hard)
if (drive_stat->drive_stat_soft)
if (drive_stat->drive_stat_library)
if (drive_stat->drive_stat_lib_acc)
if (drive_stat->drive_stat_group)
if (drive_stat->drive_stat_broken)
if (drive_stat->drive_stat_online)
if (drive_stat->drive_stat_dm)
if (drive_stat->drive_stat_serial)
if (drive_stat->drive_stat_pcl)
}
"select "
"\"DRIVE\".\"DriveDisabled\", "
"\"DRIVE\".\"DriveBroken\", "
"\"DRIVE\".\"DriveStateSoft\", "
"\"DRIVE\".\"DriveLibraryAccessible\", "
"\"DRIVE\".\"ExclusiveAppName\", "
"\"DRIVE\".\"DriveOnline\", "
"\"DRIVE\".\"DriveGroupName\", "
"\"DRIVE\".\"DriveStateHard\", "
"\"DRIVE\".\"LibraryName\", "
"\"DRIVE\".\"DrivePriority\", "
"\"DRIVE\".\"DMName\", "
"\"DRIVE\".\"DriveGeometry\", "
"\"DRIVE\".\"DriveSerialNum\", "
"\"DRIVE\".\"CartridgePCL\", "
"\"DRIVE\".\"DriveLibraryOccupied\" "
"from \"DRIVE\" "
"where \"DriveName\" = '%s';",
drive_name) != MM_DB_DATA) {
"db error, mm_get_drive_status");
return (NULL);
}
"row num mismatch, "
"mm_get_drive_status");
return (NULL);
}
if (drive_status == NULL) {
"Unable to malloc drive_status");
return (NULL);
}
return (drive_status);
}
void
"LM Status for LM, %s",
" LibraryName = %s",
" LMStateHard = %s",
" LMStateSoft = %s",
" LMDisabled = %s",
}
void
return;
}
if (lm_stat->lm_stat_name)
if (lm_stat->lm_stat_hard)
if (lm_stat->lm_stat_disabled)
if (lm_stat->lm_stat_soft)
if (lm_stat->lm_stat_library)
}
"select "
"\"LM\".\"LMStateHard\", "
"\"LM\".\"LMStateSoft\", "
"\"LM\".\"LMDisabled\", "
"\"LM\".\"LibraryName\" "
"from \"LM\" "
"where \"LMName\" = '%s';",
lm_name) != MM_DB_DATA) {
"db error, mm_get_lm_status");
return (NULL);
}
"row num mismatch, "
"mm_get_lm_status");
return (NULL);
}
"Unable to malloc lm_status");
return (NULL);
}
lm_name);
return (lm_status);
}
void
"Library Status for Library, %s",
" LibraryOnline = %s",
" LibraryDisabled = %s",
" LibraryBroken = %s",
" LMName = %s",
}
void
return;
}
if (lib_stat->lib_stat_name)
if (lib_stat->lib_stat_online)
if (lib_stat->lib_stat_disabled)
if (lib_stat->lib_stat_broken)
if (lib_stat->lib_stat_lm)
}
"select "
"\"LIBRARY\".\"LibraryOnline\", "
"\"LIBRARY\".\"LibraryDisabled\", "
"\"LIBRARY\".\"LibraryBroken\", "
"\"LIBRARY\".\"LMName\" "
"from \"LIBRARY\" "
"where \"LibraryName\" = '%s';",
library_name) != MM_DB_DATA) {
"db error, mm_get_library_status");
return (NULL);
}
"row num mismatch, "
"mm_get_library_status");
return (NULL);
}
if (library_status == NULL) {
"Unable to malloc library_status");
return (NULL);
}
return (library_status);
}
static char *
mm_sql_get_ops(char *op)
{
int x;
for (x = 0; x < num_ops; x++) {
}
}
/* Not in table */
return ("??UNKNOWN??");
}
int
{
char *new;
int new_bufsize;
return (0);
}
return (-1);
}
*bufsize = new_bufsize;
}
return (0);
}
int
int match_off)
{
int rows;
int row;
/* get object instance */
return (MM_CMD_ERROR);
}
if (rows == 0) {
"Didn't match any %s's for delete", objname);
return (INTRP_OK);
}
"notify object %s instance %s",
"mm_notify_delete: "
"error adding config event");
}
}
return (INTRP_OK);
return (MM_CMD_ERROR);
}
int
{
char *value;
/* get object instance */
return (MM_CMD_ERROR);
}
return (INTRP_OK);
}
if (value[0] == '\0') {
} else {
}
MM_ABORT("object instance");
return (MM_CMD_ERROR);
}
return (INTRP_OK);
return (MM_CMD_ERROR);
}
void
int reportmode) {
/* 3 possible reportmode formatting */
int name_rt = 1;
int value_rt = 2;
int namevalue_rt = 3;
char *value;
char *name;
char date[24];
int i;
int len;
/* database data types to mms string conversions */
value = "true";
value = "false";
}
/* mms time not set */
value = "0000 00 00 00 00 00 000";
} else {
/* mms UTC time format */
}
for (i = len; i < 23; i++) {
value[i] = '0';
}
}
}
if ((reportmode == name_rt) ||
(reportmode == namevalue_rt)) {
/* add name */
" \"%s\"",
name);
}
if ((reportmode == value_rt) ||
(reportmode == namevalue_rt)) {
}
return;
}
char *
int num_atts, int reportmode,
int print = 0;
if (print)
"create attlist clause for row %d",
row);
/* print the attr list for row starting with col_count */
"attrlist[");
/* LINTED: */
}
"]");
return (attr_buf);
}
char *
mms_list_t *format) {
int col_count = 0;
int print = 0;
/* Create the text clause for the report in cmd */
if (print)
"create text clause for row %d",
row);
/* First bracket for this text clause */
/* Do data base format conversion */
/* The function will write into text buf */
col_count ++;
} else {
/* This is an attrlist clause */
"error setting atr_buf");
if (text_buf)
return (NULL);
}
attr_buf);
}
}
/* Trailing bracket for this text text */
return (text_buf);
}
int
mms_list_t *format) {
/* 2 possible data types in report */
int data_type;
int obj_att = 1;
int att_list = 2;
char *cur_obj;
char *cur_attr;
int print = 0;
int num_atts = 0;
/* Create the text clause for the report in cmd */
if (print)
"determine formatting for this report");
data_type = 0;
/* Need to use attr list for OBJECTS */
report_work = NULL;
if (print)
"cur object is %s",
}
/* determine if attr list is needed */
object_next = NULL;
if ((object_next != NULL) &&
/* don't need an attrlist */
/* set the obj name */
/* The next object will be an attribute */
if (print)
"set obj for obj.attr, %s",
} else {
/* Need attr list */
if (print)
"set obj for attr list, %s",
}
}
if (print)
"set attr for obj.attr, %s",
}
data_type = 0;
/* This is an obj_att */
(void) mm_add_int(0, format);
if (print)
"add 0 to int list %s.\"%s\"",
}
data_type = 0;
/* This is an attr list */
/* Determine the number of attributes */
if (print)
"set attr num for %s",
cur_obj);
"select * from \"%s\" limit 1;",
cur_obj) != MM_DB_DATA) {
"db error getting attribute number");
return (1);
}
if (print)
"attr num is %d for %s",
cur_obj);
}
}
/* done */
return (0);
}
int
int buf_len;
int clause_len;
int char_size = sizeof (char);
if (text_clause == NULL) {
/* is the 1st text clause, this must fit */
return (0);
}
return (0);
}
"header len == %d, buf len == %d, "
"clause len == %d, total == %d, "
"LIMIT == %d",
return (1);
} else {
return (0);
}
}
static int
{
int report_type = 2;
int name_rt = 1;
int namevalue_rt = 3;
/* buf for whole response */
/* buf for multiple text clauses */
/* buf for a single text clause */
char *text_clause = NULL;
int number_of_rows = 0;
int row;
/* Report format */
/* CMD size limit */
int header_length;
return (1);
}
return (1);
}
/* Only return info user wants. The default is value only. */
MMS_PN_KEYWORD, NULL)) {
MMS_PN_KEYWORD, NULL)) {
MMS_PN_KEYWORD, NULL)) {
/* Generate a the number report and return */
"text[\"%d\"]",
}
text_buf);
return (0);
}
/* Build the text report */
/* there will be a text clause for each of the rows */
/* no report clause */
/* there will be no text clause in response */
number_of_rows = 0;
} else {
/* Determine the formatting for the entire report */
"error determineing report format");
"error determineing report format");
return (1);
}
}
if (number_of_rows != 0) {
/* There will be text clauses */
"response header size is %d",
}
text_clause = NULL;
"error generating text clause");
"error generating text clause");
return (1);
}
/* Check the MM_CMD_SIZE_LIMIT */
/* before appending the next text clause */
/* this command may need intermediate packets */
/* This text clause will push response over limit */
"command size over the limit");
/* add the curr text buf to the response list */
if (resp_buf)
text_buf);
node =
"Error malloc response object");
return (1);
} else {
}
if (text_buf)
}
if (text_clause)
text_clause = NULL;
}
/* clean up formatting */
if (number_of_rows == 0) {
/* add the curr text buf to the response list */
if (resp_buf)
node =
return (1);
} else {
}
/* Set the success response with no text */
} else {
/* add the curr text buf to the response list */
if (resp_buf)
text_buf);
return (1);
} else {
}
/* Set the success response with a text */
}
if (text_buf)
return (0);
return (1);
}
static void
{
"(\"VOLUME\".\"VolumeName\" = '%s')",
}
}
return;
return;
NULL);
return;
}
int
char *sql_ops;
const char *att_test;
char *att_cond;
char *obj;
char *att;
int twice = 0;
regex = 1;
}
}
}
/* Could be numeric or null string or string. */
} else {
}
} else {
}
}
if (!regex)
cur ++;
/* Just Worte a constraint value */
}
/* An object-attribute */
twice = 0;
twice = 1;
}
}
if (regex)
cur ++;
if (twice)
cur ++;
}
/*
* A multiops has two or more args hanging off the arglist.
* Insert the ops between the args by adding an arg, then add
* the ops and repeat until the last arg.
*/
/* sql regular expression is at end of list */
}
/* LINTED: dont change */
} else {
&b_size,
" %s ", sql_ops);
}
}
}
}
/* restore list to original order */
}
/* Unary ops has only one arg */
att_test = "mm_obj_has_att('%s','%s') = '%s'";
att_cond = "true";
} else {
att_cond = "false";
}
}
} else {
" %s ", sql_ops);
}
}
}
return (cur);
return (MM_CMD_ERROR);
return (MM_CMD_ERROR);
}
char *
char *object;
int off = 0;
int bufsize = 0;
int cur = 0;
return (NULL);
}
off = 0;
bufsize = 0;
}
} else {
object);
return (NULL);
}
return (buf);
}
int
/*
* return 1 if the operator is 'and'
* between constraints with indexes 'idx1' and 'idx2'
* return 0 if the operator is 'or'
*/
int oper = 1;
return (NULL);
}
oper = 1;
}
oper = 0;
}
}
}
return (oper);
}
int
char *joined[100];
int joined_count = 0;
int skip = 0;
int wrote_one = 0;
char *source_buf;
char *dest_buf;
int print_message = 0;
int i;
int y;
int j;
int k;
int x;
int l;
for (y = 0; y < 100; y ++) {
}
/* create report functins for each report onject */
joined_count = 0;
/* Make report_n() for this source */
"CREATE OR REPLACE FUNCTION "\
"report_%d_%d() RETURNS SETOF \"%s\" AS $$\n",
"select distinct \"%s\".* from \"%s\" ",
joined_count = 0;
joined_count ++;
for (j = 0; j < cmd->cmd_dest_num; j ++) {
dest_buf =
if (print_message) {
j, dest_buf);
}
source_buf)) == NULL) {
} else {
for (k = 0; k < path->mm_node_num; k++) {
skip = 0;
for (x = 0; x < joined_count; x++) {
/* same so skip */
skip = 1;
}
}
if (!skip) {
"\ncross join \"%s\" ",
joined_count ++;
}
}
}
}
if (cmd->cmd_dest_num == 0) {
";\n");
}
for (j = 0; j < cmd->cmd_dest_num; j ++) {
/* j cmd_dest_num */
if (j == 0) {
"\nwhere \n(\n");
}
dest_buf =
if (print_message) {
j, dest_buf);
}
source_buf)) == NULL) {
source_buf) == 0) {
/* same object */
wrote_one = 1;
} else {
/* no path between */
wrote_one = 1;
}
} else {
/* node[%d] has %d edges, k, */
/* path->mm_node[k]->mm_edge_num */
for (l = 0;
l++) {
/*
* if (path->mm_node[k]->
* mm_edge[l]->mm_ref_att != NULL) {
*
* }
*/
/* add this edge constraint */
wrote_one = 1;
"(\"%s\".",
} else {
"(\"%s\".",
[k+1]->mm_obj);
}
"\"%s\" = ",
} else {
"\"%s\" = ",
mm_edge[l]->mm_ref_att);
}
"\"%s\".\"%s\")\n",
mm_edge_num) {
}
}
if (k - 1 >= 0) {
}
}
}
}
int p;
/* Add all constraints here */
for (p = 0;
p < cmd->cmd_const_num;
p ++) {
if (p == 0) {
if (wrote_one)
"and\n(\n");
}
(char *)
cmd_const_list, p));
buf =
"and\n");
}
if (p + 1 ==
cmd->cmd_const_num) {
/* parenn for constraints */
}
}
/* paren for where ( */
if (wrote_one) {
");\n");
} else {
";\n");
}
}
}
"$$ LANGUAGE SQL;\n");
"mm_sql_report_func: "
"db error setting savepoint");
}
MM_DB_OK) {
"mm_sql_report_func: "
"db error rollingback savepoint");
}
}
"mm_sql_report_func: "
"db error releaseing savepoint");
}
return (1);
}
for (y = 0; y < joined_count; y ++) {
}
}
return (0);
}
int
char *joined[100];
int joined_count = 0;
int skip = 0;
int wrote_one = 0;
char *source_buf;
char *dest_buf;
int y;
int j;
int k;
int x;
int l;
int p;
int i;
for (y = 0; y < 100; y ++) {
}
/* create report functins for each report onject */
joined_count = 0;
/* Make report_n() for this source */
"CREATE OR REPLACE FUNCTION "\
"report_%d_%d() RETURNS SETOF \"%s\" AS $$\n",
"select distinct \"%s\".* from \"%s\" ",
joined_count = 0;
joined_count ++;
for (j = 0; j < cmd->cmd_dest_num; j ++) {
dest_buf =
source_buf)) == NULL) {
} else {
for (k = 0; k < path->mm_node_num; k++) {
skip = 0;
for (x = 0; x < joined_count; x++) {
/* same so skip */
skip = 1;
}
}
if (!skip) {
"\ncross join \"%s\" ",
joined_count ++;
}
}
}
}
for (j = 0; j < cmd->cmd_dest_num; j ++) {
dest_buf =
/* j cmd_dest_num */
if (j == 0) {
"\nwhere \n(\n");
}
source_buf)) == NULL) {
source_buf) == 0) {
/* same object */
wrote_one = 1;
} else {
/* no path between */
wrote_one = 1;
}
} else {
for (l = 0;
l++) {
/*
* if (path->mm_node[k]->
* mm_edge[l]->mm_ref_att != NULL) {
*
* }
*/
/* add this edge constraint */
wrote_one = 1;
"(\"%s\".",
} else {
"(\"%s\".",
[k+1]->mm_obj);
}
"\"%s\" = ",
} else {
"\"%s\" = ",
mm_edge[l]->mm_ref_att);
}
"\"%s\".\"%s\")\n",
mm_edge_num) {
}
}
if (k - 1 >= 0) {
}
}
}
}
/* Add all constraints here */
for (p = 0;
p < cmd->cmd_const_num;
p ++) {
if (p == 0) {
if (wrote_one)
"and\n(\n");
}
(char *)
cmd_const_list, p));
buf =
"and\n");
}
if (p + 1 ==
cmd->cmd_const_num) {
/* parenn for constraints */
}
}
/* paren for where ( */
if (wrote_one) {
")\n");
} else {
"\n");
}
}
}
}
" ; $$ LANGUAGE SQL;\n");
if (mm_db_txn_savepoint(db,
"mm_sql_report_func_attr: "
"db error setting savepoint");
}
MM_DB_OK) {
"mm_sql_report_func_attr: "
"db error setting savepoint");
}
}
"mm_sql_report_func_attr: "
"db error releaseing savepoint");
}
return (1);
}
for (y = 0; y < joined_count; y ++) {
}
}
return (0);
}
int
{
char *joined[100];
int joined_count = 0;
int skip = 0;
char *source_buf_i;
char *source_buf_j;
int y;
int i;
int j;
int k;
int x;
int l;
for (y = 0; y < 100; y ++) {
}
/* Generate all report_n() for this command */
"error creating report funcs");
return (1);
}
joined_count = 0;
for (i = 0; i < cmd->cmd_source_num; i ++) {
/*
* ex, i = 0
* report_0() t0, "DM"
* t0 is arbitrary table alias
*/
"\nreport_%d_%d() t%d, \"%s\" ",
joined_count ++;
"cross join ");
}
}
/* Add objects to FROM clause */
/* add implied constraints between source objects */
for (i = 0; i < cmd->cmd_source_num; i ++) {
source_buf_j = (char *)
source_buf_i)) != NULL) {
for (k = 0; k < path->mm_node_num; k++) {
skip = 0;
for (x = 0; x < joined_count; x++) {
mm_obj) == 0) {
/* same so skip */
skip = 1;
}
}
if (!skip) {
"\ncross join \n\"%s\" ",
joined_count ++;
}
}
}
}
}
for (i = 0; i < cmd->cmd_source_num; i ++) {
for (j = 0; j < p_key->mm_att_num; j ++) {
"(t%d.\"%s\" = \"%s\".\"%s\")\n",
}
}
}
}
/* Now add the implied path constraints */
for (i = 0; i < cmd->cmd_source_num; i ++) {
source_buf_j = (char *)
source_buf_i)) != NULL) {
for (l = 0;
l++) {
/*
* if (path->mm_node[k]->
* mm_edge[l]->mm_ref_att != NULL) {
*
* }
*/
/* add this edge constraint */
/* will always need an 'and' */
"(\"%s\".",
} else {
"(\"%s\".",
[k+1]->mm_obj);
}
"\"%s\" = ",
} else {
"\"%s\" = ",
mm_edge[l]->mm_ref_att);
}
"\"%s\".\"%s\")\n",
}
}
}
}
}
for (y = 0; y < joined_count; y ++) {
}
return (0);
return (1);
}
int
int j;
int i;
char *source_buf_0;
buf);
/* get pkey for this source */
for (j = 0; j < p_key->mm_att_num; j ++) {
"(\"%s\".\"%s\" in \n",
"(select \"%s\".\"%s\" from "\
"report_0_%d() t%d, \"%s\" where\n",
j,
for (i = 0; i < p_key->mm_att_num; i ++) {
"(t%d.\"%s\" = \"%s\".\"%s\") ",
j,
}
}
}
}
return (INTRP_OK);
return (MM_CMD_ERROR);
}
static int
int *offset, int host_ident)
{
char *sql_ops;
const char *att_test;
char *att_cond;
char *obj;
char *att;
int need_int_cast = 0;
int need_host_ident = 0;
int print_message = 0;
if (print_message)
" cmdbuf == %s",
} else {
if (print_message)
" cmd_buf is NULL");
}
if (print_message)
" (node->pn_type & MMS_PN_STRING)");
/* Could be numeric or null string or string. */
/* Still support NULLSTR ?? */
" <= ") == 0 ||
" >= ") == 0) {
" <> ") == 0) {
} else {
}
} else {
if (host_ident) {
"pg_host_ident(");
}
if (host_ident) {
}
}
}
if (print_message)
" node->pn_type == MMS_PN_OBJ");
/* An object-attribute */
} else {
}
if (print_message)
"(node->pn_flags & MMS_PN_MULTIOPS)");
"numeq") == 0) ||
"numne") == 0) ||
"numlt") == 0) ||
"numle") == 0) ||
"numgt") == 0) ||
"numge") == 0)) {
need_int_cast = 1;
}
if (print_message)
" %s",
"hosteq") == 0) ||
"hostne") == 0)) {
"pg_host_ident(");
need_int_cast = 1;
need_host_ident = 1;
}
}
/*
* A multiops has two or more args hanging off the arglist.
* Insert the ops between the args by adding an arg, then add
* the ops and repeat until the last arg.
*/
/* sql regular expression is at end of list */
}
}
&off, need_host_ident)) {
"mm_sql_trans_match_exp: "
"error translating match expression");
return (1);
}
}
if (need_int_cast) {
need_int_cast = 0;
}
&cmd->cmd_bufsize,
" %s ", sql_ops);
}
}
/* restore list to original order */
}
if (print_message)
"(node->pn_flags & MMS_PN_UNARYOPS)");
/* Unary ops has only one arg */
&off, need_host_ident)) {
"mm_sql_trans_match_exp: "
"error translating match expression");
return (1);
}
/* isset */
" IS NOT NULL");
} else {
/* notnot */
" ISNULL");
}
att_test = "mm_obj_has_att('%s','%s') = '%s'";
att_cond = "true";
} else {
att_cond = "false";
}
} else {
" %s ", sql_ops);
&off, need_host_ident)) {
"mm_sql_trans_match_exp: "
"error translating match expression");
return (1);
}
}
}
return (0);
return (1);
NULL);
return (1);
}
void
{
char *number_buf = NULL;
/* This function will append the number buf to cmd_buf */
if (number_buf != NULL)
return;
}
if (buf)
if (final_buf)
return;
}
char *
{
/* This function returns a buf of the number clause */
int range1 = 0;
int range2 = 0;
int val;
return (NULL);
}
/*
* Subtract one from the number because the postgres data index
* starts at zero and the mmp command number starts at one.
*/
/* Have a range */
/* get the 1st and last arg */
MMS_PN_STRING, &work);
MMS_PN_STRING, &work);
"an arg in range cannot be NULL");
return (buf);
}
range1 = 1;
} else {
return (buf);
}
val -= 1;
return (buf);
} else {
return (buf);
}
} else {
return (buf);
}
range1 -= 1;
range2 -= 1;
val -= 1;
}
"found a number clause, "
"but didn't write any sql");
return (buf);
}
return (buf);
return (NULL);
return (NULL);
}
int
{
/*
* Get number clause range, number[a..b] or number[a]
*/
/* no number */
return (0);
}
/* number range */
return (0);
"number-clause range first-%d",
return (0);
}
"range %d-last",
return (0);
}
return (0);
}
return (1);
}
/* single number */
return (0);
}
void
{
return;
}
if (buf)
if (final_buf)
return;
}
char *
{
int ordercnt = 0;
char *sql_ops;
int need_int_cast = 0;
MMS_PN_CLAUSE, &work);
ordercnt++,
MMS_PN_CLAUSE, &work)) {
if (ordercnt == 0) {
} else {
}
"op == %s",
"numhilo") == 0) ||
"numlohi") == 0)) {
need_int_cast = 1;
"int4(");
}
if (need_int_cast) {
}
}
return (buf);
}
return (buf);
return (NULL);
}
void
{
int dbstatus;
char *dbmessage;
return;
}
}
int
/* Checks is str is already in list */
/* If str exists, do nothing */
/* Else add to list and inc num */
return (1);
}
"mm_add_match_list: "
"error adding char");
return (1);
}
return (0);
}
int
/* LINTED: mm_wka may be used in the future */
{
int off = 0;
cmd->cmd_bufsize = 0;
}
/* Look up the match clause */
/* No match clause, chek for volname */
/* Found a volname */
} else {
/* No match and no volname */
return (1);
}
}
&cmd->cmd_const_list)) {
"- out of memory");
return (1);
}
cmd->cmd_const_num ++;
return (0);
}
/* We have a match clause */
return (1);
}
return (1);
}
/* List way */
&cmd->cmd_const_list)) {
return (1);
}
/* Array Way */
cmd->cmd_const_num ++;
/* List TEST */
return (0);
return (MM_CMD_ERROR);
}
int
/* LINTED: mm_wka may be used in the future */
{
int source_count = 0;
int skip = 0;
cmd->cmd_source_num = 0;
return (1);
}
skip = 0;
/* already have this as a source */
skip = 1;
}
if (!skip) {
/* List way */
&cmd->cmd_source_list)) {
"char to source list");
return (1);
}
/* Array Way */
source_count ++;
}
}
/* List TEST */
return (0);
}
void
{
int skip = 0;
skip = 0;
/* already have this as a dest */
skip = 1;
}
if (!skip) {
/* List way */
&cmd->cmd_dest_list)) {
"char to source list");
}
/* Array Way */
cmd->cmd_dest_num ++;
}
}
/* sql regular expression is at end of list */
}
}
/* restore list to original order */
}
} else {
}
}
}
void
cmd->cmd_const_num = 0;
}
void
cmd->cmd_dest_num = 0;
}
void
cmd->cmd_source_num = 0;
}
int
/* LINTED: mm_wka may be used in the future */
{
/* List way */
if (mm_add_char("VOLUME",
&cmd->cmd_dest_list)) {
"char to source list");
}
/* Array Way */
cmd->cmd_dest_num ++;
return (0);
}
return (1);
}
}
/* List TEST */
return (0);
}
int
/*
*/
/* Check for the objects in the source list */
/* Add constraint for CARTRIDGE */
(void) mm_add_to_dest(cmd,
"CARTRIDGEGROUPAPPLICATION");
if (const_buf)
"\"CARTRIDGEGROUPAPPLICATION\"."
"\"ApplicationName\" = '%s'",
app_name);
}
/* Add constraint for VOLUME */
(void) mm_add_to_dest(cmd,
"VOLUME");
if (const_buf)
"\"VOLUME\"."
"\"ApplicationName\" = '%s'",
app_name);
}
/*
*/
/* Add constraint for DRIVE */
(void) mm_add_to_dest(cmd,
"DRIVEGROUPAPPLICATION");
if (const_buf)
"\"DRIVEGROUPAPPLICATION\"."
"\"ApplicationName\" = '%s'",
app_name);
}
/* Add constraint for MOUNTPHYSICAL */
(void) mm_add_to_dest(cmd,
"MOUNTPHYSICAL");
if (const_buf)
"\"MOUNTPHYSICAL\"."
"\"ApplicationName\" = '%s'",
app_name);
}
/*
* System/connection constraints
*/
/* Add constraint for APPLICATION */
(void) mm_add_to_dest(cmd,
"APPLICATION");
if (const_buf)
"\"APPLICATION\"."
"\"ApplicationName\" = '%s'",
app_name);
}
/* Add constraint for DRIVE */
(void) mm_add_to_dest(cmd,
"CONNECTION");
if (const_buf)
"\"CONNECTION\"."
"\"ConnectionClientName\" = '%s'",
app_name);
}
if (const_buf)
return (0);
}
void
{
int off;
return;
}
/* Command does not have a report clause */
} else {
/* TEMP - Trace out our source info */
}
} else {
/* TEMP - Trace out our dest info */
}
/* Build Constraint List */
} else {
/* TEMP - Trace out our const info */
}
/* For non priv-clients, check the source list */
/* Add any additional constraits necessary */
/* ie. VOLUME.ApplicationName = cci_client */
/* both source + dest may need adds */
"add non-priv constraints");
/* Need to check source list and */
/* add constraints as necessary */
"error adding non-priv "
"client constraints");
}
"const list after additions, %d",
cmd->cmd_const_num);
} else {
"skip constraints forpriv client");
}
/* If unique is specified in the reportmode clause, insert DISTINCT */
MMS_PN_KEYWORD, NULL)) {
"DISTINCT ");
}
/* show all attributes */
} else {
/*
* More than one object column reference can't be be
* ambiguous, specify object and attribute.
*/
"\"%s\".\"%s\",",
}
}
off--; /* overwrite the last comma */
"mm_path_match_report: "
"db error creating helper functions");
return;
}
if (mm_sql_report(cmd)) {
"mm_path_match_report: "
"error generating final response");
}
return;
return;
NULL);
return;
}
/*
* uses its own db connection
* to set drive 1, DRIVE.DriveStateHard to 'loaded' :
* mm_sql_update_state(&mm_data, "DRIVE", "DriveStateHard", "loaded",
* "DriveName", "drive1");
*/
#define MM_SQL_UPDATE_STATE "update \"%s\" "\
"set \"%s\" = '%s' "\
"where \"%s\" = '%s';"
void
{
"mm_sql_update_state: "
"db error updating db states");
}
return;
}
int
/* LINTED: db is used by this function */
#if 1
/* TEMP - dont request, always clear */
*auto_clear = 1;
*request_oper = 0;
return (0);
#else
"select "
"\"AskClearDriveAtLMConfig\","
"\"ClearDriveAtLMConfig\" "
"from \"SYSTEM\";");
if (rc != MM_DB_DATA) {
return (1);
}
return (1);
}
"yes") == 0) {
*request_oper = 1;
}
/* Don't ask the oper */
"yes") == 0) {
*auto_clear = 1;
}
return (0);
#endif
}
int
/* LINTED: a mm_wka arg is required by all cmd functions */
return (MM_DEPEND_DONE);
}
int
"drive %s, cartridge %s",
"oper") == 0) &&
"MMS") == 0)) {
/* Found the wka of oper */
break;
}
}
return (1);
}
"Unable to malloc mm_command_t: %s",
return (1);
}
return (MM_CMD_ERROR);
}
return (0);
}
/* response and returns a pointer to the error code */
"Error parsing command response");
return (0);
}
/* Might not be an error response */
return (0);
}
return (1);
}
return (0);
}
int
/* 1. DMP detach */
/* 2. DMP release */
"non-physical clear, add detach");
/* Need both drive and dm set */
"this non-physical clear");
return (MM_CMD_ERROR);
}
/* Get DM Name */
"select \"DMName\" from \"DRIVE\" "
"where \"DRIVE\".\"DriveName\" = '%s';",
"db error");
return (MM_CMD_ERROR);
}
"row num mismatch");
return (MM_CMD_ERROR);
}
"missing dm name");
return (MM_CMD_ERROR);
}
/* Send a detach */
MM_DMP_DETACH) == NULL) {
"mm_non_physical_clear_cmd_func: "
"error adding dmp detach");
}
return (MM_DISPATCH_DEPEND);
}
"non-physical clear, add release");
/*
* Detach has returned
* check error, update states
* Add Unload command
*/
"DM_E_NOEXISTHANDLE")) {
"DM doesn't know the handle, "
"skip DMP unload, "
"send LMP unmount");
/* Clear depend error flags */
} else {
/* detach returned handle in use */
"non-physical clear_drive -> "
"DMP detach error, "
"handle may be inuse");
return (MM_CMD_ERROR);
}
}
"DM is not using handle, send DMP release");
MM_DMP_RELEASE) == NULL) {
"mm_non_physical_clear_cmd_func: "
"error adding dmp release");
}
return (MM_DISPATCH_DEPEND);
}
"non-physical clear, schedule unload");
/* unload returned an error */
}
"select distinct \"CARTRIDGE\"."
"\"CartridgeID\" from \"CARTRIDGE\""
"cross join \"DRIVE\""
"where"
"((\"CARTRIDGE\".\"LibraryName\" "
"= \"DRIVE\".\"LibraryName\")"
"and"
"(\"DRIVE\".\"DriveName\" = '%s')"
"and"
"(\"CARTRIDGE\".\"CartridgePCL\" = "
"\"DRIVE\".\"CartridgePCL\"));",
"db error");
return (MM_CMD_ERROR);
}
"row num mismatch");
return (MM_CMD_ERROR);
}
"mm_non_physical_clear_cmd_func: "
"db error deleting TASKCARTRIDGE");
}
"mm_non_physical_clear_cmd_func: "
"db error deleting TASKDRIVE");
}
"mm_non_physical_clear_cmd_func: "
"db error deleting TASKLIBRARY");
}
"mm_non_physical_clear_cmd_func: "
"db error deleting TASK");
}
"where \"CartridgeID\" = '%s';",
"mm_non_physical_clear_cmd_func: "
"db error deleting MOUNTLOGICAL");
}
"where \"CartridgeID\" = '%s';",
"mm_non_physical_clear_cmd_func: "
"db error deleting MOUNTPHYSICAL");
}
"mm_non_physical_clear_cmd_func: "
"error scheduling delay unload");
}
"non-physical clear complete, delay unload scheduled");
return (MM_DISPATCH_AGAIN);
}
"mm_non_physical_clear_cmd_func: unknown cmd state");
return (MM_CMD_ERROR);
}
#define MM_CLEAR_START 0
#define MM_CLEAR_SLOTSCAN 20
#define MM_CLEAR_DETACH 21
#define MM_CLEAR_RELEASE 22
#define MM_CLEAR_UNLOAD 23
#define MM_CLEAR_UNMOUNT 24
#define MM_CLEAR_FINAL 25
int
int rc;
/* This is a physical unmount */
/* detach, release, unload, unmount */
/* Clear depend error flags, */
/* On the 1st cmd state of clear drive */
/* ignore any errors */
/* This clear drive may be running after */
/* A DMP activate which may have errored */
/* Try to clear anyways */
"library name not set for clear drive");
return (MM_CMD_ERROR);
}
/* Confirm LM is connected and active */
"select distinct "
"\"LM\".\"LMStateSoft\" from \"LM\""
"cross join \"LIBRARY\""
"where((\"LM\".\"LibraryName\" = "
"\"LIBRARY\".\"LibraryName\")"
"and(\"LIBRARY\".\"LibraryName\" = '%s'));",
if (rc != MM_DB_DATA) {
return (MM_CMD_ERROR);
}
"library, %s, has no lm assigned",
return (MM_CMD_ERROR);
}
"not ready") == 0) {
return (MM_NO_DISPATCH);
}
} else {
"lm state = %s, cancel clear drive",
return (MM_CMD_ERROR);
}
"drive -> %s, send scan",
/* Add LMP scan command for this drive */
"Error adding LMP scan");
return (MM_CMD_ERROR);
} else {
"Added LMP scan");
}
/* If DRIVE is occupied and has pcl set */
/* MM will need to send lmp scan for the */
/* cartridge as well */
"cmi_pcl already set, %s",
return (MM_DISPATCH_DEPEND);
}
/* set mount_info->cmi_pcl */
"select distinct "
"\"DRIVE\".\"CartridgePCL\""
"from \"DRIVE\" "
"where"
" \"DRIVE\".\"DriveName\" = '%s'; ",
"mm_clear_drive_cmd_func");
return (MM_CMD_ERROR);
}
"error getting pcl from drive");
return (MM_CMD_ERROR);
}
0, 0), MM_NON_MMS_CART) == 0) {
"drive loaded with non-mms cart");
/* If non-mms cart return */
/* since this is not part of MMS */
/* MM does not need a cart scan */
return (MM_DISPATCH_DEPEND);
}
0, 0), "") != 0) {
/* DRIVE.pcl was set */
mm_db_results, 0, 0),
}
return (MM_DISPATCH_DEPEND);
}
/* Command state when a lmp scan for slot is needed */
/* Drive scan has completed */
"drive scan complete, send scan of PCL");
/* Add LMP scan command for this drive */
mount_info->cmi_library)) {
"Error adding LMP scan");
return (MM_CMD_ERROR);
} else {
"Added LMP scan");
}
}
return (MM_DISPATCH_DEPEND);
}
/* Send the DMP detach command */
"physical clear, add detach");
/* Need drive set */
"cmi_drive is NULL for "
"this physical clear");
return (MM_CMD_ERROR);
}
/* set mount_info->cmi_pcl */
"select distinct "
"\"DRIVE\".\"CartridgePCL\""
"from \"DRIVE\" "
"where"
" \"DRIVE\".\"DriveName\" = '%s'; ",
"mm_clear_drive_cmd_func");
return (MM_CMD_ERROR);
}
"error getting pcl from drive");
return (MM_CMD_ERROR);
}
0, 0), "") == 0) {
"LMP scan of drive shows %s is clear",
/* Set States For a Clear Drive */
"update \"DRIVE\" set "
"\"DriveStateHard\" = 'unloaded', "
"\"DMName\" = DEFAULT, "
"\"DriveLibraryOccupied\" = 'f' "
"where \"DriveName\" = '%s';",
"mm_clear_drive_cmd_func: "
"db error updating DRIVE");
}
/* Delete any mountphysical, mountlogical, */
/* or stalehandle */
"delete from \"MOUNTLOGICAL\" "
"where \"DriveName\" = '%s';",
"mm_clear_drive_cmd_func: "
"db error deleting MOUNTLOGICAL");
}
"delete from \"STALEHANDLE\" "
"where \"DriveName\" = '%s';",
"mm_clear_drive_cmd_func: "
"db error deleting STALEHANDLE");
}
"delete from \"MOUNTPHYSICAL\" "
"where \"DriveName\" = '%s';",
"mm_clear_drive_cmd_func: "
"db error deleting MOUNTPHYSICAL");
}
if (mm_has_depend(cmd)) {
return (MM_DEPEND_DONE);
}
return (MM_CMD_DONE);
}
0, 0), MM_NON_MMS_CART) == 0) {
"this is a clear drive for a non-mms cartridge");
/* Look in the response to the scan to */
/* find the pcl in this drive */
"pcl already set to %s",
} else {
"pcl is NULL for a non-MMS cart");
return (MM_CMD_ERROR);
}
} else {
mm_db_results, 0, 0),
}
"pcl is NULL ");
return (MM_CMD_ERROR);
}
"pcl set to %s",
/* Get DM Name */
"select \"DMName\" from \"DRIVE\" "
"where \"DRIVE\".\"DriveName\" = '%s';",
"db error");
return (MM_CMD_ERROR);
}
"row num mismatch");
return (MM_CMD_ERROR);
}
"missing dm name in DRIVE, "
"dm may already be detached, check STALEHANDLE");
/* Try getting DMName from STALEHANDLE */
"select \"DMName\" from \"STALEHANDLE\" "
"where \"STALEHANDLE\".\"DriveName\" = '%s';",
"db error");
return (MM_CMD_ERROR);
}
"Can't find STALEHANDLE, continue unmount");
goto start;
}
}
/* Send a detach */
MM_DMP_DETACH) == NULL) {
"mm_clear_drive_cmd_func: "
"error adding dmp detach");
}
return (MM_DISPATCH_DEPEND);
}
/* Send the DMP release command */
"physical clear, add release");
/*
* Detach has returned
* check error, update states
* Add Unload command
*/
"DM_E_NOEXISTHANDLE")) {
"DM doesn't know the handle, "
"skip DMP unload, "
"send LMP unmount");
/* Clear depend error flags */
} else {
/* detach returned handle in use */
"DMP detach error, "
"handle may be inuse");
return (MM_CMD_ERROR);
}
}
"DM is not using handle, send DMP release if dm is ready");
/* Check, if DM is not activated, don't send a release */
"select \"DMStateSoft\" from \"DM\" "
"where \"DM\".\"DMName\" = '%s';",
"db error");
return (MM_CMD_ERROR);
}
"Can't find DM, continue unmount");
return (MM_CMD_ERROR);
}
"present") == 0) ||
"absent") == 0) ||
"disconnected") == 0)) {
/* DM cannot process release */
/* Continue to unmount */
"DMStateSoft = %s, don't send release, "
"continue with unmount",
goto start;
}
"DMStateSoft = %s, about to send release",
MM_DMP_RELEASE) == NULL) {
"mm_clear_drive_cmd_func: "
"error adding dmp release");
}
return (MM_DISPATCH_DEPEND);
}
/* Always send a DMP unload before the physicalunmount */
/* If MM knows what DM to send to */
/* Try to send an unload now */
"didn't find DM Name, "
"skip DMP unload");
goto start;
}
"sending %s DMP unload",
mount_info->cmi_dm);
MM_DMP_UNLOAD) == NULL) {
"mm_clear_drive_func: "
"error adding dmp unload");
}
return (MM_DISPATCH_DEPEND);
}
/* DMP unload has completed, ignore any errors */
/* and continue with the LMP unmount */
"error during DMP unload, "
"continue with LMP unmount");
/* Clear depend error flags */
}
"physical clear, add unmount");
/*
* LMP unmount command
*/
/* ********************* */
/* TODO: FIX SIDE NAME!! */
"Unable to malloc mm_command_t: %s",
return (MM_CMD_ERROR);
}
"side 1",
"side 1");
return (MM_DISPATCH_DEPEND);
}
/*
* LMP mount has returned
* check for error,
* Return MM_DEPEND_DONE on success
*/
return (MM_CMD_ERROR);
}
/* Set States For a Clear Drive */
"update \"DRIVE\" set "
"\"DriveStateHard\" = 'unloaded', "
"\"DMName\" = DEFAULT, "
"\"DriveLibraryOccupied\" = 'f' "
"where \"DriveName\" = '%s';",
"mm_clear_drive_cmd_func: "
"db error updating DRIVE");
}
/* Delete any mountphysical, mountlogical, or stalehandle */
"where \"DriveName\" = '%s';",
"mm_clear_drive_cmd_func: "
"db error deleting MOUNTLOGICAL");
}
"where \"DriveName\" = '%s';",
"mm_clear_drive_cmd_func: "
"db error deleting STALEHANDLE");
}
"where \"DriveName\" = '%s';",
"mm_clear_drive_cmd_func: "
"db error deleting MOUNTPHYSICAL");
}
if (mm_has_depend(cmd)) {
return (MM_DEPEND_DONE);
}
return (MM_CMD_DONE);
}
"mm_clear_drive_cmd_func: unknown cmd state");
return (MM_CMD_ERROR);
}
int nonphysical) {
if (drive_name == NULL) {
"mm_add_clear_drive passed null drive_name");
return (NULL);
}
"mm_add_clear_drive passed null mm_data");
return (NULL);
}
"mm_add_clear_drive passed null db pointer");
return (NULL);
}
"select \"LMName\", \"LibraryName\" "\
"from \"LM\" " \
"where \"LibraryName\" in "\
"(select \"LibraryName\" from "\
"\"DRIVE\" where \"DriveName\" = '%s');",
drive_name) != MM_DB_DATA) {
"mm_add_clear_drive");
return (NULL);
}
"mm_add_clear_drive");
return (NULL);
}
/* Check the queue, if there is already a clear drive, */
/* do not add another */
/* If other is found, return a pointer to that clear drive */
drive_name) == 0) &&
"already have a clear "
"drive for %s , %s",
return (cur_cmd);
}
}
}
PQgetvalue(lm_name, 0, 0)) == 0) {
/* Found the wka of lm */
break;
}
}
PQgetvalue(lm_name, 0, 0)) != 0)) {
/* bad wka */
return (NULL);
}
"Unable to malloc mm_command_t: %s",
return (NULL);
}
if (parent_cmd != NULL) {
}
return (NULL);
}
if (nonphysical) {
} else {
}
/* Force or not */
/* Cart_pcl */
&cmd->cmd_mount_info);
}
return (cmd);
}