diff --git a/smaclient-1.1 b/smaclient-1.1 new file mode 100644 index 0000000..9e2a092 --- /dev/null +++ b/smaclient-1.1 @@ -0,0 +1,10493 @@ +#!/bin/bash +verrel=1.1 +# ============================================================================= +# +# Bash script to provide access to z/VM System Management functions. +# Written by Leland Lucius one fun week in the snowy winter of 2011. +# +# Released under the Artistic License 2.0. Full license text can be found at: +# +# http://opensource.org/licenses/artistic-license-2.0 +# +# Read below for requirements, but one of my goals when writing it was to try +# and use as few external programs as possible. Not for any technical reasons, +# I just wanted to see if I could do it mostly with bash. +# +# You can use "smaclient smiucv" to build the embedded IUCV helper utility. This +# will allow you to use IUCV instead of TCP/IP as the transport between smaclient +# and the SMAPI servers. You must install gcc for the build, but do not need +# it once built. The helper will be built in the same directory where smaclient +# is located. +# +# When using smaclient, you need to provide the destination host, authorized +# userid and password. These values can be specified in four locations: +# +# 1) /etc/smaclient.conf +# 2) ~/.smaclient +# 3) environment variables SMHOST, SMUSER, and SMPASS +# 4) arguments to smaclient +# +# For /etc/smaclient.conf and ~/.smaclient, you can specify any or all of the +# following variables: +# +# smhost +# For TCP/IP, specify the SMAPI host and port number. The format is: +# hostname/portnumber +# For IUCV, specify the literal "IUCV". +# +# smuser +# For TCP/IP, specify the userid authorized to use SMAPPI. +# For IUCV, there's no need to specify this, but it doesn't hurt. +# +# smpass +# For TCP/IP, specify the corresponding password. +# For IUCV, there's no need to specify this, but it doesn't hurt. +# +# An example ~/.smaclient: +# +# smhost="myzvm/44444" +# smuser="vsmuser" +# smpass="secret" +# +# Every smaclient function requires the smhost, smuser, and smpass as described +# above. In addition, the "target" option is also required and its value +# should be as decribed in the System Management manual. +# +# An example invocation: +# +# smaclient Image_Active_Configuration_Query -T guestnm +# +# produces: +# +# Memory size: 1 +# Memory units: 3 (GB) +# Share type: 1 (Relative) +# Share value: 100 +# CPU count: 1 +# +# CPUs: +# Address: 0 +# ID: FF0D111120978000 +# Status: 1 (Base) +# +# Devices: +# Device 0009 is 1 (CONS) +# Device 000C is 2 (RDR) +# Device 000D is 3 (PUN) +# Device 000E is 4 (PRT) +# Device 1000 is 5 (DASD) +# Device 1001 is 5 (DASD) +# Device 1002 is 5 (DASD) +# Device 1003 is 5 (DASD) +# Device 1004 is 5 (DASD) +# Device 2000 is 5 (DASD) +# +# To get a list of supported SMAPI functions, enter "smaclient" without any +# arguments. +# +# Notes and warnings: +# +# I have not tested all of the functions completely as I simply don't use +# them. If you find something amiss, feel free to let me know and I'll see +# about fixing it. +# +# Use at your own risk. I wrote it, but by using it, you have determined +# that the risk is acceptable and I will not be held responsible. +# +# This script doesn't attempt to validate option values. That is left up to +# the SMAPI routines. So, you'll have to consult the "Systems Management +# Application Programming" book (SC24-6234 or equivalent). An example error +# where the message isn't very friendly: +# +# smaclient Virtual_Network_Vswitch_Delete -D -T smuser -s tswitch -u 1234 +# Syntax error in parameter 12: Numeric value greater than maximum +# +# In this case, paramter 12 is the update_system_config_indicator as it is +# the 12th paramter listed in the Input Paramters for this function. +# +# ============================================================================= + +# ============================================================================= +# +# Requirements: +# +# bash built with support for "/dev/tcp" if using SMAPI TCP interface +# dd from "coreutils" package +# tr from "coreutils" package +# getopt from "util-linux" package +# xxd from "vim" package +# smiucv if you want to use the SMAPI IUCV interface +# +# Some SMAPI functions require OPTION DIAG88 in the VSMWORKn VMs directory +# entries. +# +# Global variables used: +# +# smfile SMAPI file descriptor +# smhost SMAPI host name (or IP) and port number (host/port) or "IUCV" +# smuser SMAPI authorized userid +# smpass SMAPI authorized password +# smfunc SMAPI function name +# smtarg SMAPI target identifier (guest or auth list entry name) +# resp SMAPI response in hexadecimal representation +# reqid1 SMAPI request id from immediate response +# resplen SMAPI response length +# reqid2 SMAPI request id from response +# retc SMAPI return code from response +# reas SMAPI reason code from response +# debug Set to "yes" to enable debugging code +# +# Parsing related: +# +# desc Description of function +# required Required options for usage display and parameter checking +# optional Optional options for usage display +# opts Short options for passing to "getopt" +# optl Long options for passing to "getopt" +# usesparms Set to "r" for required positional parms, "o" for optional +# positional parms, and "n" for no positional parms +# +# ============================================================================= + +# ============================================================================= +# Display a message based on the SMAPI return code, reason code, and function +# +# Note: I copied the messages from SC24-6234-00. If this is a problem, I will +# remove them and just go with a generic type of message. +# ============================================================================= +function showerror +{ + # Define local variables + local m pp rr + + case "${retc}_${reas}_${smfunc}" in + + # RC_OK + 0_0_Query_API_Functional_Level) m="The API functional level is z/VM V5.3" ;; + 0_0_*) m="Request successful" ;; + 0_4_Image_CPU_Define) m="CPU defined, but CPU affinity suppressed" ;; + 0_4_Shared_Memory_Create) m="Segment was created, but specified userid could not be found to give RSTD access" ;; + 0_4_Shared_Memory_Replace) m="Segment was replaced, but specified userid could not be found to give RSTD access" ;; + 0_8_*) m="Request successful; object directory offline" ;; + 0_12_Name_List_Add) m="Request successful; new list created" ;; + 0_12_Shared_Memory_*) m="Request successful; NAMESAVE statement already exists in directory" ;; + 0_12_*) m="Image not active" ;; + 0_16_*) m="Request successful; no more entries, list destroyed" ;; + 0_20_Directory_Manager_Local_Tag_Set_DM) m="Use not allowed by exit routine." ;; + 0_20_*) m="No output; user(s) not authorized for specified segment" ;; + 0_24_*) m="Request successful; virtual network LAN removed" ;; + 0_28_Asynchronous_Notification_*) m="No matching entries found" ;; + 0_28_Image_SCSI_Characteristics_Query_DM) m="There are no SCSI characteristics for this image." ;; + 0_28_Shared_Memory_Query) m="Query request successful, but segment not found" ;; + 0_28_*) m="No matching entries found. Return buffer is empty." ;; + 0_32_*) m="Name was not in list" ;; + 0_36_*) m="Name is already in list" ;; + 0_40_*) m="Request successful; new virtual switch created" ;; + 0_44_*) m="Request successful; virtual switch removed" ;; + 0_66_*) m="Multiple DEFINE or MODIFY statements are erased in system config" ;; + 0_100_*) m="Asynchronous operation succeeded" ;; + 0_104_*) m="Asynchronous operation in progress" ;; + 0_108_*) m="Asynchronous operation failed" ;; + 0_540_*) m="The API functional level is z/VM V5.4" ;; + 0_610_*) m="The API functional level is z/VM V6.1" ;; + 0_611_*) m="The API functional level is the updated z/VM V6.1 SPE release" ;; + 0_612_*) m="The API functional level is the updated z/VM V6.1 SPE release with APAR VM64917 applied" ;; + 0_620_*) m="The API functional level is z/VM V6.2" ;; + 0_621_*) m="The API functional level is z/VM V6.2 with added support for network monitoring metrics and HiperSockets Vswitch bridge" ;; + + # RC_WNG + 4_4_*) m="Request does not exist" ;; + 4_5_*) m="Unrestricted LAN" ;; + 4_6_*) m="No authorized users" ;; + 4_8_*) m="Device does not exist" ;; + 4_28_*) m="Return buffer is empty" ;; + 4_3000_*) m="VMRELOCATE TEST error" ;; + 4_3001_*) m="No active relocations found" ;; + 4_3008_*) m="System is not a member of an SSI cluster" ;; + 4_3009_*) m="System was IPLed with theREPAIR IPL parameter" ;; + + # RC_ERR + 8_2_*) m="Invalid access user" ;; + 8_3_*) m="Invalid op value" ;; + 8_4_Virtual_Network_LAN_Access) m="Invalid promiscuity value" ;; + 8_4_Image_Definition_Delete_DM) m="Directory entry to be deleted not found" ;; + 8_4_System_Performance_Threshold_Enable) m="Performance monitoring virtual server not found" ;; + 8_8_*) m="Device does not exist" ;; + 8_10_*) m="Device not available for attachment" ;; + 8_12_Page_or_Spool_Volume_Add) m="Device not a volume" ;; + 8_12_VMRELOCATE_Image_Attributes) m="target_identifier not logged on" ;; + 8_13_*) m="Match key length does not match the match key specified" ;; + 8_14_*) m="Free modes not available" ;; + 8_18_*) m="Volume does not exist" ;; + 8_19_*) m="Volume is CP owned and cannot be used" ;; + 8_20_Image_Volume_Share) m="Volume is CP system and cannot be used" ;; + 8_20_Page_or_Spool_Volume_Add) m="Volume label already CP_OWNED on this system or in this system's configuration" ;; + 8_24_Page_or_Spool_Volume_Add) m="Error linking parm disk" ;; + 8_24_Image_Definition_Async_Updates) m="Unable to write ASYNCH file" ;; + 8_28_*) m="Parm disk not RW" ;; + 8_32_*) m="System configuration not found on parm disk" ;; + 8_34_*) m="System configuration has bad data" ;; + 8_36_*) m="Specified length is not valid" ;; + 8_38_*) m="CP disk modes not available" ;; + 8_40_*) m="Parm disk is full" ;; + 8_42_*) m="Parm disk access not allowed" ;; + 8_44_*) m="No link password for parm disk was provided" ;; + 8_46_*) m="Parm disk password is incorrect" ;; + 8_48_*) m="Parm disk is not in server's user directory" ;; + 8_50_*) m="Error with CPRELEASE of parm disk" ;; + 8_52_*) m="Error in access of CPACCESS parm disk" ;; + 8_241_*) m="Internal communication error" ;; + 8_1821_*) m="Relocation domain domain_name does not exist" ;; + 8_1822_*) m="User target_identifier cannot be set to a new relocation domain domain_name without the FORCE ARCHITECTURE option" ;; + 8_1823_*) m="A multiconfiguration virtual machine cannot be relocated" ;; + 8_2783_*) m="Invalid LAN ID" ;; + 8_2795_*) m="Invalid LAN parameter" ;; + 8_3000_*) m="VMRELOCATE MOVE error" ;; + 8_3002_*) m="Invalid parameter name" ;; + 8_3003_*) m="Invalid parameter operand" ;; + 8_3004_*) m="Required parameter missing" ;; + 8_3006_*) m="SSI is not in a STABLE state" ;; + 8_3007_*) m="The volume ID or slot is not available on all systems in the SSI" ;; + 8_3008_*) m="System is not a member of an SSI cluster" ;; + 8_3010_*) m="VMRELOCATE modify error" ;; + 8_3011_*) m="No unique CP_OWNED slot available on system and in System Config" ;; + 8_3012_*) m="Volume does not exist" ;; + 8_3013_*) m="Volume is offline" ;; + 8_3014_*) m="Volume does not support sharing" ;; + 8_*) m="VMRELOCATE_Status returned an error. The RS nnnn represents the HCPnnnn message." ;; + + # RCERR_SYNTAX + 24_13_*) m="Metadata entry name value length exceeds allowable length (1024)" ;; + 24_19_*) m="Parameter value not recognized" ;; + 24_*) + pp=$(( reas / 100 )) + rr=$(( reas % 100 )) + case "${rr}" in + 1) m="First character of listname is a colon \":\"" ;; + 10) m="Characters not \"0123456789\"" ;; + 11) m="Unsupported function" ;; + 13) m="Length is greater than maximum or exceeds total length" ;; + 14) m="Length is less than minimum" ;; + 15) m="Numeric value less than minimum or null value encountered" ;; + 16) m="Characters not \"0123456789ABCDEF\"" ;; + 17) m="Characters not \"0123456789ABCDEF-\"" ;; + 18) m="Numeric value greater than maximum" ;; + 19) m="Unrecognized value" ;; + 23) m="Conflicting parameter specified" ;; + 24) m="Unspecified required parameter" ;; + 25) m="Extraneous parameter specified" ;; + 26) m="Characters not \"ABCDEFGHIJKLMNOPQRSTUVWXYZ\"" ;; + 36) m="Characters not \"ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789\"" ;; + 37) m="Characters not \"ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-\"" ;; + 42) m="Characters not \"ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789@#$+-:\"" ;; + 43) m="Characters not \"ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789@#$+-:_\"" ;; + 44) m="Characters not \"ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789@#$+-:_=\"" ;; + 45) m="Invalid SFS syntax" ;; + 88) m="Unexpected end of data" ;; + 99) m="Non-breaking characters: non-blank, non-null, non-delete, non-line-end, non-carriage return, non-line-feed" ;; + *) m="Unknown syntax error: ${rr}" ;; + esac + + m="Syntax error in parameter ${pp}: ${m}" + ;; + + # RCERR_FILE_NOT_FOUND + 28_0_*) m="Namelist file not found" ;; + + # RCERR_FILE_CANNOT_BE_UPDATED + 36_0_*) m="Namelist file cannot be updated" ;; + + # RCERR_AUTH + 100_0_*) m="Request is authorized" ;; + 100_4_*) m="Authorization deferred to directory manager" ;; + 100_8_*) m="Request not authorized by external security manager" ;; + 100_12_*) m="Request not authorized by directory manager" ;; + 100_16_*) m="Request not authorized by server" ;; + 100_20_*) m="Target image not authorized for function" ;; + + # RCERR_NO_AUTHFILE + 104_0_*) m="Authorization file not found" ;; + + # RCERR_AUTHFILE_RO + 106_0_*) m="Authorization file cannot be updated" ;; + + # RCERR_EXISTS + 108_0_*) m="Authorization file entry already exists" ;; + + # RCERR_NO_ENTRY + 112_0_*) m="Authorization file entry does not exist" ;; + + # RCERR_USER_PW_BAD + 120_0_*) m="Authentication error; userid or password not valid" ;; + + # RCERR_PW_EXPIRED + 128_0_*) m="Authentication error; password expired" ;; + + # RCERR_ESM + 188_*) m="Internal server error; ESM failure: ${reas}" ;; + + # RCERR_PW_CHECK + 192_*) m="Internal server error; cannot authenticate user/password: ${reas}" ;; + + # RCERR_IMAGEOP + 200_0_*) m="Image operation error" ;; + 200_4_*) m="Image not found" ;; + 200_8_*) m="Image already active" ;; + 200_12_*) m="Image not active" ;; + 200_16_*) m="Image being deactivated" ;; + 200_24_*) m="List not found" ;; + 200_28_*) m="Some images in list not activated" ;; + 200_32_*) m="Some images in list not deactivated" ;; + 200_36_Image_Recycle) m="Some images in list not recycled" ;; + 200_36_Image_Deactivate) m="Specified time results in interval greater than max allowed" ;; + + # RCERR_IMAGEDEVU + 204_0_*) m="Image device usage error" ;; + 204_2_*) m="Input image device number not valid" ;; + 204_4_*) m="Image device already exists" ;; + 204_8_*) m="Image device does not exist" ;; + 204_12_*) m="Image device is busy" ;; + 204_16_*) m="Image device is not available" ;; + 204_20_*) m="Image device already connected" ;; + 204_24_*) m="Image device is not a tape drive, or cannot be assigned/reset" ;; + 204_28_*) m="Image device is not a shared DASD" ;; + 204_28_Image_Device_Reset) m="Image device is not a shared DASD" ;; + 204_28_*) m="Image device already defined as type other than network adapter" ;; + 204_32_*) m="Image device is not a reserved DASD" ;; + 204_36_*) m="I/O error on image device" ;; + 204_40_*) m="Virtual Network Adapter not deleted" ;; + 204_44_*) m="DASD volume cannot be deleted" ;; + 204_48_*) m="Virtual network adapter is already disconnected" ;; + + # RCERR_IMAGEDISKU + 208_0_*) m="Image disk usage error" ;; + 208_4_*) m="Image disk already in use" ;; + 208_8_*) m="Image disk not in use" ;; + 208_12_*) m="Image disk not available" ;; + 208_16_*) m="Image disk cannot be shared as requested" ;; + 208_20_*) m="Image disk shared in different mode" ;; + 208_28_*) m="Image disk does not have" ;; + 208_32_*) m="Incorrect password specified for image disk" ;; + 208_36_*) m="Image disk does not exist" ;; + 208_1157_*) m="MDISK DEVNO parameter requires the device to be a free volume" ;; + + # RCERR_IMAGECONN + 212_0_*) m="Active image connectivity error" ;; + 212_4_*) m="Partner image not found" ;; + 212_8_Virtual_Network_Adapter_Query) m="Adapter does not exist" ;; + 212_8_*) m="Image not authorized to connect" ;; + 212_12_*) m="LAN does not exist" ;; + 212_16_*) m="LAN owner LAN name does not exist" ;; + 212_20_*) m="Requested LAN owner not active" ;; + 212_24_*) m="LAN name already exists with different attributes" ;; + 212_28_*) m="Image device not correct type for requested connection" ;; + 212_32_*) m="Image device not connected to LAN" ;; + 212_36_*) m="Virtual switch already exists" ;; + 212_40_*) m="Virtual switch does not exist" ;; + 212_44_*) m="Image already authorized" ;; + 212_48_*) m="VLAN does not exist" ;; + 212_52_*) m="Maximum number of connections reached" ;; + 212_96_*) m="Unknown reason" ;; + + # RCERR_IMAGECPU + 216_2_*) m="Input virtual CPU value out range" ;; + 216_4_*) m="Virtual CPU not found" ;; + 216_12_*) m="Image not active" ;; + 216_24_*) m="Virtual CPU already exists" ;; + 216_28_*) m="Virtual CPU address beyond allowable range defined in directory" ;; + 216_40_*) m="Processor type not supported on your system" ;; + + # RCERR_VOLUME + 300_0_*) m="Image volume operation successful" ;; + 300_8_*) m="Device not found" ;; + 300_10_*) m="Device not available for attachment" ;; + 300_12_*) m="Device not a volume" ;; + 300_14_*) m="Free modes not available" ;; + 300_16_*) m="Device vary online failed" ;; + 300_18_*) m="Volume label not found in system configuration" ;; + 300_20_*) m="Volume label already in system configuration" ;; + 300_22_*) m="Parm disks 1 and 2 are same" ;; + 300_24_*) m="Error linking parm disk (1 or 2)" ;; + 300_28_*) m="Parm disk (1 or 2) not RW" ;; + 300_32_*) m="System configuration not found on parm disk 1" ;; + 300_34_*) m="System configuration has bad data" ;; + 300_36_*) m="Syntax errors updating system configuration file" ;; + 300_38_*) m="CP disk modes not available" ;; + 300_40_*) m="Parm disk (1 or 2) is full" ;; + 300_42_*) m="Parm disk (1 or 2) access not allowed" ;; + 300_44_*) m="Parm disk (1 or 2) PW not supplied" ;; + 300_46_*) m="Parm disk (1 or 2) PW is incorrect" ;; + 300_48_*) m="Parm disk (1 or 2) is not in server's user directory" ;; + 300_50_*) m="Error in release of CPRELEASE parm disk (1 or 2)" ;; + 300_52_*) m="Error in access of CPACCESS parm disk (1 or 2)" ;; + + # RCERR_INTERNAL + 396_0_*) m="Internal system error" ;; + 396_*) m=$(printf "Internal system error - product-specific return code (try HELP HCP%03dE in CMS)\n" ${reas}) ;; + + # RCERR_IMAGEDEF + 400_0_*) m="Image or profile definition error" ;; + 400_4_*) m="Image or profile definition not found" ;; + 400_8_*) m="Image or profile name already defined" ;; + 400_12_*) m="Image or profile definition is locked" ;; + 400_16_*) m="Image or profile definition cannot be deleted" ;; + 400_20_*) m="Image prototype is not defined" ;; + 400_24_*) m="Image or profile definition is not locked" ;; + 400_40_*) m="Multiple user statements" ;; + + # RCERR_IMAGEDEVD + 404_0_*) m="Image device definition error" ;; + 404_4_*) m="Image device already defined" ;; + 404_8_*) m="Image device not defined" ;; + 404_12_*) m="Image device is locked" ;; + 404_24_Image_Disk_Copy_DM) m="Image device type not same as source" ;; + 404_24_*) m="Image device is not locked" ;; + 404_28_*) m="Image device size not same as source" ;; + + # RCERR_IMAGEDISKD + 408_0_*) m="Image disk definition error" ;; + 408_4_*) m="Image disk already defined" ;; + 408_8_*) m="Image disk not defined" ;; + 408_12_*) m="Image device is locked" ;; + 408_16_*) m="Image disk sharing not allowed by target image definition" ;; + 408_24_*) m="Requested image disk space not available" ;; + 408_28_*) m="Image disk does not have required password" ;; + 408_32_*) m="Incorrect password specified for image disk" ;; + + # RCERR_IMAGECONND + 412_0_*) m="Image connectivity definition error" ;; + 412_4_*) m="Partner image not found" ;; + 412_16_*) m="Parameters do not match existing directory statement" ;; + 412_28_*) m="Image device not correct type for requested connection" ;; + + # RCERR_PROTODEF + 416_0_*) m="Prototype definition error" ;; + 416_4_*) m="Prototype definition not found" ;; + 416_8_*) m="Prototype already exists" ;; + + # RC_DASD_DM + 420_4_*) m="Group, region, or volume name is already defined" ;; + 420_8_*) m="Group, region, or volume name is not defined" ;; + 420_12_*) m="Region name is not included in the group" ;; + 420_36_*) m="The requested volume is offline or is not a DASD device" ;; + + # RCERR_SEGMENT_DM + 424_4_*) m="Namesave statement already exists" ;; + 424_8_*) m="Segment name not found" ;; + + # RCERR_NOTIFY + 428_4_*) m="Duplicate subscription" ;; + 428_8_*) m="No matching entries" ;; + + # RCERR_TAG + 432_4_*) m="Tag name is already defined" ;; + 432_8_*) m="Tag name is not defined" ;; + 432_12_*) m="Tag ordinal is already defined" ;; + 432_16_*) m="Tag is in use in one or more directory entries, can not be revoked" ;; + 432_20_*) m="Use not allowed by exit routine" ;; + + # RCERR_PROFILED + 436_4_*) m="Profile included not found" ;; + 436_40_*) m="Multiple profiles included" ;; + + # RCERR_POLICY_PW + 444_0_*) m="Password policy error" ;; + 444_4_*) m="Password too long" ;; + 444_8_*) m="Password too short" ;; + 444_12_*) m="Password content does not match policy" ;; + + # RCERR_POLICY_ACCT + 448_0_*) m="Account policy error" ;; + 448_4_*) m="Account number too long" ;; + 448_8_*) m="Account number too short" ;; + 448_12_*) m="Account number content does not match policy" ;; + + # RCERR_TASK + 452_4_*) m="Task not found" ;; + + # RCERR_SCSI + 456_4_*) m="LOADDEV statement not found" ;; + + # RC_IPL_DM + 460_4_*) m="Image does not have an IPL statement" ;; + + # RCERR_DM + 500_0_*) m="Directory manager request could not be completed" ;; + 500_4_*) m="Directory manager is not accepting updates" ;; + 500_8_*) m="Directory manager is not available" ;; + 500_12_*) m="Directory manager has been disabled" ;; + 500_16_*) m="Directory manager was interrupted" ;; + 500_20_*) m="Password format not supported" ;; + + # RCERR_LIST_DM + 504_*) m="Target ID not added - product-specific return code: ${reas}" ;; + + # RCERR_CPU_DM + 520_24_*) m="Only one base CPU may be defined" ;; + 520_28_*) m="Input virtual CPU value out of range" ;; + 520_30_*) m="CPU not found" ;; + 520_32_*) m="Maximum allowable number of virtual CPUs is exceeded" ;; + 520_45_*) m="The Cryptographic Coprocessor Facility (CCF) is not installed on this system" ;; + 520_2826_*) m="SCPDATA contains invalid UTF-8 data" ;; + + # RCERR_ASYNC_DM + 592_0_*) m="Asynchronous operation started" ;; + 592_*) m="Asynchronous operation started - product-specific asynchronous operation ID: ${reas}" ;; + + # RCERR_INTERNAL_DM + 596_*) m="Internal directory manager error - product-specific return code: ${reas}" ;; + + # RCERR_SHSTOR + 600_8_*) m="Bad page range" ;; + 600_12_*) m="User not logged on" ;; + 600_16_*) m="Could not save segment" ;; + 600_20_*) m="Not authorized to issue internal system command or is not authorized for RSTD segment" ;; + 600_24_*) m="Conflicting parameters" ;; + 600_28_*) m="Segment not found or does not exist" ;; + 600_299_*) m="Class S (skeleton) segment file already exists" ;; + + # RCERR_VIRTUALNETWORKD + 620_14_*) m="Free modes not available" ;; + 620_22_*) m="System config parm disks 1 and 2 are same" ;; + 620_24_*) m="Error linking parm disk (1 or 2)" ;; + 620_28_*) m="Parm disk (1 or 2) not RW" ;; + 620_32_*) m="System config not found on parm disk 1" ;; + 620_34_*) m="System config has bad data" ;; + 620_36_*) m="Syntax errors updating system config" ;; + 620_38_*) m="CP disk modes not available" ;; + 620_40_*) m="Parm disk (1 or 2) is full" ;; + 620_42_*) m="Parm disk (1 or 2) access not allowed" ;; + 620_44_*) m="Parm disk (1 or 2) PW not supplied" ;; + 620_46_*) m="Parm disk (1 or 2) PW is incorrect" ;; + 620_48_*) m="Parm disk (1 or 2) is not in server's directory" ;; + 620_50_*) m="Error in release of CPRELEASE parm disk (1 or 2)" ;; + 620_52_*) m="Error in access of CPACCESS parm disk (1 or 2)" ;; + 620_54_*) m="DEFINE VSWITCH statement already exists in system config" ;; + 620_58_*) m="MODIFY VSWITCH statement to userid not found in system config" ;; + 620_60_*) m="DEFINE VSWITCH statement does not exist in system config" ;; + 620_62_*) m="DEFINE operands conflict, cannot be updated in the system config" ;; + 620_64_*) m="Multiple DEFINE or MODIFY statements found in system config" ;; + + # RCERR_VMRM + 800_8_*) m="No measurement data exists" ;; + 800_12_*) m="Error in update buffer or processing syntax check" ;; + 800_16_*) m="Not authorized to access file" ;; + 800_24_*) m="Error writing file(s) to directory" ;; + 800_28_*) m="Specified configuration file not found" ;; + 800_32_*) m="Internal error processing updates" ;; + + # RCERR_SERVER + 900_4_*) m="Custom exec not found" ;; + 900_8_*) m="Worker server was not found" ;; + 900_12_*) m="Specified function does not exist" ;; + 900_16_*) m="Internal server error - DMSSIPTS entry for function is invalid" ;; + 900_20_*) m="Total length does not match the specified input data" ;; + 900_24_*) m="Error accessing SFS directory" ;; + 900_28_*) m="Internal server error - error with format of function output" ;; + 900_32_*) m="Internal server error - response from worker server was not valid" ;; + 900_36_*) m="Specified length was not valid, out of valid server data range" ;; + 900_40_*) m="Internal server socket error" ;; + 900_68_*) m="Unable to access LOHCOST server" ;; + 900_99_*) m="A system change occurred during the API call - reissue the API call to obtain the data." ;; + + *) m="Unrecognized return code ${retc} and reason code ${reas} from ${smfunc}" ;; + esac + + echo -e "${m}" +} + +# ============================================================================= +# Check for successful completion, show message if needed, and bail if error +# ============================================================================= +function checkandfail +{ + if [ ${retc} -ne 0 -o ${reas} -ne 0 ] + then + showerror + exit 1 + fi +} + +# ============================================================================= +# Remove embedded blanks +# ============================================================================= +function removeblanks +{ + IFS="" + echo "${*}" +} + +# ============================================================================= +# Retrieve an 8 byte int from the SMAPI response buffer +# ============================================================================= +function get8 +{ + # Make sure there's enough left in the response buffer + if [ ${#resp} -lt 16 ] + then + echo "get8 called with insufficient data" + exit 1 + fi + + # Grab the next 8 bytes (16 hex digits) + eval ${1}=$(( 16#${resp:0:16} )) + + # And remove them from the response buffer + resp="${resp:16}" +} + +# ============================================================================= +# Retrieve a 4 byte int from the SMAPI response buffer +# ============================================================================= +function get4 +{ + # Make sure there's enough left in the response buffer + if [ ${#resp} -lt 8 ] + then + echo "get4 called with insufficient data" + exit 1 + fi + + # Grab the next 4 bytes (8 hex digits) + eval ${1}=$(( 16#${resp:0:8} )) + + # And remove them from the response buffer + resp="${resp:8}" +} + +# ============================================================================= +# Retrieve a 1 byte value from the SMAPI response buffer +# ============================================================================= +function get1 +{ + # Make sure there's enough left in the response buffer + if [ ${#resp} -lt 2 ] + then + echo "get1 called with insufficient data" + exit 1 + fi + + # Grab the next byte (2 hex digits) + eval ${1}=$(( 16#${resp:0:2} )) + + # And remove them from the response buffer + resp="${resp:2}" +} + +# ============================================================================= +# Retrieve characters from the SMAPI response buffer +# +# The variable name that will receive the characters must be passed when +# calling this function. +# ============================================================================= +function getchars +{ + # Define local variables + local len + + # Convert length to hex length + len=$(( $1 * 2 )) + + # Set the variable to an empty string if the length is zero + if [ ${len} -eq 0 ] + then + eval ${2}="" + return + fi + + # Make sure there's enough left in the response buffer + if [ ${#resp} -lt ${len} ] + then + echo "getchars called with insufficient data" + exit 1 + fi + + # Grab the string and convert back to character + eval ${2}='"$(echo -n ${resp:0:len} | xxd -r -p)"' + + # And remove it from the response buffer + resp="${resp:len}" +} + +# ============================================================================= +# Retrieve a string from the SMAPI response buffer +# +# The variable name that will receive the string must be passed when calling +# this function. +# ============================================================================= +function getstring +{ + # Define local variables + local len + + # Grab the string length + get4 len + + # Grab the string + getchars ${len} ${1} +} + +# ============================================================================= +# Retrieve an array of strings from the SMAPI response buffer +# +# The variable name that will receive the array must be passed when calling +# this function. +# ============================================================================= +function getstringarray +{ + # Define local variables + local array_length array_offset entry_length entry_index + + # Get the entire array length and convert to hex length + get4 array_length + array_length=$(( array_length * 2 )) + + # Process all array entries + array_offset=0 + entry_index=0 + while [ ${array_offset} -lt ${array_length} ] + do + # Make sure there's enough left in the response buffer + if [ $(( array_length - array_offset )) -lt 8 ] + then + echo "Premature end in getstringarray" + exit 1 + fi + + # Grab the next 4 bytes (8 hex digits) + entry_length=$(( 16#${resp:array_offset:8} * 2 )) + array_offset=$(( array_offset + 8 )) + + # Set the variable to an empty string if the length is zero + if [ ${entry_length} -eq 0 ] + then + eval ${1}[${entry_index}]="" + else + # Make sure there's enough left in the response buffer + if [ $(( array_length - array_offset )) -lt ${entry_length} ] + then + echo "Premanture end in getstringarray" + exit 1 + fi + + # Grab the string and convert back to character + eval ${1}[${entry_index}]='"$(echo -n ${resp:array_offset:entry_length} | xxd -r -p)"' + + # Bump to next input entry + array_offset=$(( array_offset + entry_length )) + fi + + # Bump to next output entry + entry_index=$(( entry_index + 1 )) + done + + # Remove it from the response buffer + resp="${resp:array_offset}" +} + +# ============================================================================= +# Retrieve an null terminated (ASCIIZ) string from the SMAPI response buffer +# +# The variable name that will receive the string must be passed when calling +# this function. +# ============================================================================= +function getasciiz +{ + # Define local variables + local i + + # Preset variable + eval ${1}="" + + # Find first null byte + for (( i = 0; i < ${#resp}; i += 2 )) + do + if [ "${resp:i:2}" == "00" ] + then + # Grab the string and convert back to character + eval ${1}='"$(echo -n ${resp:0:i} | xxd -r -p)"' + + # Remove it (and the null terminator) from the response buffer + resp="${resp:$(( i + 2 ))}" + break + fi + done +} + +# ============================================================================= +# Convert value to hex representation of 8 byte int +# ============================================================================= +function int8 +{ + printf "%016x" $(( ${1} & 0xffffffffffffffff )) +} + +# ============================================================================= +# Convert value to hex representation of 4 byte int +# ============================================================================= +function int4 +{ + printf "%08x" $(( ${1} & 0xffffffff )) +} + +# ============================================================================= +# Convert value to hex representation of 1 byte int +# ============================================================================= +function int1 +{ + printf "%02x" $(( ${1} & 0xff )) +} + +# ============================================================================= +# Convert string to hex representation for specified length +# ============================================================================= +function chars +{ + echo -n "${2:0:$1}" | xxd -p +} + +# ============================================================================= +# Convert string to hex representation prepended with string length +# ============================================================================= +function string +{ + local s="${*}" + + int4 ${#s} + echo -n "${s}" | xxd -p +} + +# ============================================================================= +# Convert string to hex representation with ASCIIZ appended +# ============================================================================= +function asciiz +{ + echo -e -n "${*}\x00" | xxd -p +} + +# ============================================================================= +# Convert array of strings to hex representation +# ============================================================================= +function stringarray +{ + # Define local variables + local s a + + # Build hex representation of array + a="" + while [ ${#} -gt 0 ] + do + # Grab the next entry + s="${1}" + shift + + # Do not allow null entries + if [ ${#s} -eq 0 ] + then + s=" " + fi + + # Append to output "array" + a=${a}$(string "${s}") + done + + # Get rid of any blanks (inserted by xxd) + a=$(removeblanks ${a}) + + # Calc length of entire array and output it along with the array itself + int4 $(( ${#a} / 2 )) + echo -n "${a}" +} + +# ============================================================================= +# Send request to the SMAPI server +# ============================================================================= +function smapi +{ + # Define local variables + local s iucv + + # Remember the actual function being requested + smfunc=${1} + shift + + # Prepend the general parameters and remove embedded blanks + s=$(removeblanks \ + $(string "${smfunc}") \ + $(string "${smuser}") \ + $(string "${smpass}") \ + $(string "${smtarg}") \ + ${*}) + + # For debugging + if [ "${debug}" == "yes" ] + then + { int4 $(( ${#s} / 2 )) ; echo -n ${s} ; } | xxd -r -p >req + fi + + # Connect to the SMAPI host + if [ "${smhost}" != "IUCV" ] + then + exec 3<>/dev/tcp/"${smhost}" + + # Bail if we couldn't connect + if [ $? -ne 0 ] + then + echo "Failed to connect to ${smhost}" + exit 1 + fi + + # Calculate and prepend request length, convert from hex to + # binary representation, send to the SMAPI server, and wait + # for the response. + resp=$({ int4 $(( ${#s} / 2 )) ; echo -n ${s} ; } | xxd -r -p >&3 && xxd -p <&3) + else + # Calculate and prepend request length, convert from hex to + # binary representation, send to the SMAPI server, and wait + # for the response. + resp=$({ int4 $(( ${#s} / 2 )) ; echo -n ${s} ; } | xxd -r -p | smiucv | xxd -p) + fi + + # Get rid of any blanks inserted by xxd (don't quote it) + resp=$(removeblanks ${resp}) + + # For debugging + if [ "${debug}" == "yes" ] + then + echo "${resp}" | xxd -r -p >resp + fi + + # Retrieve the common results sent with every response + get4 reqid1 + + # Retrieve secondary result if available + resplen=0 + reqid2=0 + retc=0 + reas=0 + + if [ ${#resp} -gt 0 ] + then + get4 resplen + get4 reqid2 + get4 retc + get4 reas + fi + + # For debugging + #echo "reqid1 $reqid1" + #echo "resplen $resplen" + #echo "reqid2 $reqid2" + #echo "retc $retc" + #echo "reas $reas" + + # Close SMAPI file descriptor ... I know, WAY too anal + if [ "${smhost}" != "IUCV" ] + then + eval 3>&- + fi +} + +# ============================================================================= +# Wait for a request that is being processed asynchronously +# ============================================================================= +function waitforasync +{ + # Define local variables + local opid secs + + opid=$(int4 "${1}") + secs=1 + + echo "Waiting for asynchronous request ${1}" + while true + do + sleep ${secs} + + smapi "Query_Asynchronous_Operation_DM" ${opid} + if [ ${retc} -ne 0 -o ${reas} -ne 104 ] + then + break + fi + + #secs=$(( secs * 2 )) + done + + if [ ${retc} -eq 0 -a ${reas} -eq 100 ] + then + reas=0 + fi +} + +# ============================================================================= +# Send the request to the SMAPI server and wait for async requests +# ============================================================================= +function execute_and_wait +{ + # Define local variables + local opid="" + + # Submit the request + smapi ${@} + + # Handle async response + if [ ${retc} -eq 592 ] + then + # The operation id will be part of the response buffer or + # will be the reason code + if [ ${reas} -eq 0 ] + then + # (Not precisely correct, but hopefully it'll cover all cases} + if [ ${#resp} -ge 4 ] + then + get4 opid + fi + else + opid=${reas} + fi + + # Go wait for it to complete + if [ -z "${opid}" ] + then + echo "Unable to determine operation ID" + exit 1 + fi + + waitforasync ${opid} + fi +} + +# ============================================================================= +# Send the request to the SMAPI server without checking for errors. +# +# This function can only be called by a SMAPI function handler since its name +# is used as part of the SMAPI request. +# ============================================================================= +function execute_no_check +{ + # Define local variables + local caller + + # Retrieve caller info + eval caller=("$(caller 0)") + + # Execute request and wait for the response + execute_and_wait "${caller[1]}" ${@} +} + +# ============================================================================= +# Send the request to the SMAPI server and check success. +# +# This function can only be called by a SMAPI function handler since its name +# is used as part of the SMAPI request. +# ============================================================================= +function execute +{ + # Retrieve the caller's name + local caller + + # Retrieve caller info + eval caller=("$(caller 0)") + + # Execute request and wait for the response + execute_and_wait "${caller[1]}" ${@} + + # Check for error + checkandfail +} + +# ============================================================================= +# Execute using keyword arguments +# ============================================================================= +function execute_keywords +{ + local caller + + # Retrieve caller info + eval caller=("$(caller 0)") + + # Generic setup + required=() + optional=() + opts="" + optl="" + usesparms="o" + + # Parse the command line + parseopts + + # Execute request and wait for the response + execute_and_wait "${caller[1]}" "${addparms}" + + # Check for error + checkandfail +} + +# ============================================================================= +# Execute using keyword arguments...bypass error checking +# ============================================================================= +function execute_keywords_no_check +{ + local caller + + # Retrieve caller info + eval caller=("$(caller 0)") + + # Generic setup + required=() + optional=() + opts="" + optl="" + usesparms="o" + + # Parse the command line + parseopts + + # Execute request and wait for the response + execute_and_wait "${caller[1]}" "${addparms}" +} + +# ============================================================================= +# Retrieve and display simple array from response buffer +# ============================================================================= +function showstringarray +{ + # Define local variables + local i array + + # Retrieve the array + getstringarray array + + # Show all the entries + for (( i = 0; i < ${#array[@]}; i++ )) + do + echo "${array[i]}" + done +} + +# ============================================================================= +# Retrieve and display ASCIIZ array from response buffer +# ============================================================================= +function showasciizarray +{ + # Define local variables + local array len + + # Calculate response length + len=$(( $1 * 2 )) + + # Retrieve and process array entries + echo "${resp:0:len}" | xxd -r -p | tr '\000' '\n' + + # Remove it from the response buffer + resp="${resp:len}" +} + +# ============================================================================= +# Load array of records from stdin +# ============================================================================= +function loadarray +{ + # Define local variables + local i record + + # Load array from stdin + OIFS="${IFS}" + IFS=$'\n' + i=0 + eval ${1}="()" + while read record + do + # Ensure records do not exceend max length + if [ ${#record} -gt 72 ] + then + echo "Record #$(( i + 1 )) is ${#record} bytes which exceeds the maximum of 72" + echo "'${record}'" + exit 1 + fi + + # Add new record to array + eval ${1}[${i}]="\${record}" + i=$(( i + 1 )) + done + IFS="${OIFS}" +} + +# ============================================================================= +# Display function usage +# ============================================================================= +function usage +{ + # Define local variables + local f i + + # Use the function name passed in or get the name of the caller + f="${1}" + if [ -z "${f}" ] + then + set -- $(caller 1) + f="${2}" + fi + + # Give 'em a little helping hand + echo + echo "${desc}" + echo + echo "Usage: $(basename ${0}) ${f} [OPTION]... [PARAMETER]..." + echo + echo "Required general options:" + echo " -T | --target target image or authorization entry name" + + # Show function related required parameters + if [ -n "${required}" ] + then + echo + echo "Required ${f} options:" + for (( i = 0; i < ${#required[@]}; i++ )) + do + echo "${required[i]}" + done + fi + + echo + echo "Optional general options:" + echo " -H | --smhost hostname/port of SMAPI server" + echo " : specify IUCV if SMAPI IUCV is desired" + echo " : the smiucv command must be available" + echo " -U | --smuser authorized SMAPI userid" + echo " -P | --smpass authorized SMAPI password" + echo " -? | --help output (this) usage information" + echo + echo " smhost, smuser, and/or smpass may also be specified in" + echo " /etc/smaclient.conf, ~/.smaclient, and/or environment variables." + + # Show function related optional parameters + if [ -n "${optional}" ] + then + echo + echo "Optional ${f} options:" + for (( i = 0; i < ${#optional[@]}; i++ )) + do + echo "${optional[i]}" + done + fi + + exit 1 +} + +# ============================================================================= +# Parse command line options +# +# Variables that must be set prior to calling this function: +# +# desc Description of function +# required Required options for usage display and parameter checking +# optional Optional options for usage display +# opts Short options for passing to "getopt" +# optl Long options for passing to "getopt" +# usesparms Set to "r" for required positional parms, "o" for optional +# positional parms, and "n" for no positional parms +# +# ============================================================================= +function parseopts +{ + # Define local variables + local reqopts caller t + + # Copy existing values and make local since they will be modified + local opts="${opts}" optl="${optl}" + + # Build array used to determine if all required options were specified + reqopts=(" -T | --target target image or authorization entry name" \ + "${required[@]}") + + # Lines with ":" are informational...remove them + reqopts=("${reqopts[@]/*: *}") + + # Retrieve the caller's name + set -- $(caller 0) + caller="${2}" + + # Add the general options + opts="H:U:P:T:D?${opts}" + if [ -n "${optl}" ] + then + optl=",${optl}" + fi + optl="smhost:,smuser:,smpass:,target:,help${optl}" + + # Parse the command line (quotes around argv are a must!) + t=$(getopt -o "${opts}" -l "${optl}" -- "${argv[@]}") + + # Try to give the user a little help if parsing failed + if [ ${?} -ne 0 ] + then + usage "${caller}" + fi + + # Empty out the argv array as it is going to get rebuilt + argv=() + addparms="" + + # Break up parsing result and assign to positional parameters + # ("eval" and quotes are required) + eval set -- "${t}" + + # Process positional parameters + while [ ${#} -gt 0 ] + do + # Locate and remove current option from required opts array + reqopts=("${reqopts[@]/*${1} *}") + + # Handle the general options + case "${1}" in + -H | --smhost) + shift + smhost="${1}" + ;; + + -U | --smuser) + shift + smuser="${1}" + ;; + + -P | --smpass) + shift + smpass="${1}" + ;; + + -T | --target) + shift + smtarg="${1}" + ;; + + -D) + debug="yes" + ;; + + -\? | --help) + usage "${caller}" + ;; + + *) + # If positional parameters were specified on the command + # line and the SMAPI function handler doesn't expect any, + # then complain and bail. + if [ "${1}" == "--" -a ${usesparms} == "n" -a ${#} -gt 1 ] + then + echo "Unexpected positional parameter(s)" + usage "${caller}" + fi + + # Otherwise transfer option and/or positional to argv array + argv[${#argv[@]}]="${1}" + + # And build 6.1+ additional input parameters + if [ "${1}" != "--" ] + then + addparms="${addparms}$(asciiz """${1}""")" + fi + ;; + esac + + # Remove option from positionals + shift + done + + # Check to make sure all of the required options were specified + reqopts="${reqopts[*]}" + if [ -n "${reqopts// }" ] + then + echo "Required option not specified" + usage "${caller}" + fi + + # These required parameters must be checked specifically since + # they may come from locations other than the command line. + if [ -z "${smhost}" ] + then + echo "Host/port (smhost) not specified" + usage "${caller}" + fi + + if [ "${smhost}" != "IUCV" -a -z "${smuser}" ] + then + echo "Authorized userid (smuser) not specified" + usage "${caller}" + fi + + if [ "${smhost}" != "IUCV" -a -z "${smpass}" ] + then + echo "Authorized password (smpass) not specified" + usage "${caller}" + fi +} + +# ============================================================================= +# SMAPI Function: Asynchronous_Notification_Disable_DM +# ============================================================================= +function Asynchronous_Notification_Disable_DM +{ + # Define local variables + local i entity_type communication_type port_number ip_address + local encoding subscriber_data + + # Define info for parser + desc="Stop receiving notification updates for specified entities" + required=(" -c | --comm communication type" \ + " : 1 = TCP" \ + " : 2 = UDP" \ + " -p | --port port number" \ + " -i | --ip IP address") + optional=(" -t | --type entity type" \ + " : 1 = DIRECTORY" \ + " -e | --encoding encoding of notification" \ + " : 0 = Unspecified (defaults to 1)" \ + " : 1 = ASCII" \ + " : 2 = EBCDIC" \ + " -d | --data subscriber data") + + opts="c:p:i:t:e:d:" + optl="comm:,port:,ip:,type:,encoding:,data:" + usesparms="n" + + # Parse the command line + parseopts + + # Initialize optional fields + entity_type="1" + encoding="0" + subscriber_data="" + + # Process options + for (( i = 0; i < ${#argv[@]}; i++ )) + do + case "${argv[i]}" in + -c | --comm) + i=$(( i + 1 )) + communication_type="${argv[i]}" + ;; + + -p | --port) + i=$(( i + 1 )) + port_number="${argv[i]}" + ;; + + -i | --ip) + i=$(( i + 1 )) + ip_address="${argv[i]}" + ;; + + -d | --data) + i=$(( i + 1 )) + subscriber_data="${argv[i]}" + ;; + + -t | --type) + i=$(( i + 1 )) + entity_type="${argv[i]}" + ;; + + -e | --encoding) + i=$(( i + 1 )) + encoding="${argv[i]}" + ;; + esac + done + + # Build and send the request + execute $(int1 "${entity_type}") \ + $(int1 "${communication_type}") \ + $(int4 "${port_number}") \ + $(string "${ip_address}") \ + $(int1 "${encoding}") \ + $(string "${subscriber_data}") + + # Tell user it was successful + echo "Subscription disabled" +} + +# ============================================================================= +# SMAPI Function: Asynchronous_Notification_Enable_DM +# ============================================================================= +function Asynchronous_Notification_Enable_DM +{ + # Define local variables + local i entity_type subscription_type communication_type port_number + local ip_address encoding subscriber_data + + # Define info for parser + desc="Receive notification when updates occur to specified entities" + required=(" -s | --sub subscription type" \ + " : 1 = INCLUDE" \ + " : 2 = EXCLUDE" \ + " -c | --comm communication type" \ + " : 1 = TCP" \ + " : 2 = UDP" \ + " -p | --port port number" \ + " -i | --ip IP address") + optional=(" -t | --type entity type" \ + " : 1 = DIRECTORY" \ + " -e | --encoding encoding of notification" \ + " : 0 = Unspecified (defaults to 1)" \ + " : 1 = ASCII" \ + " : 2 = EBCDIC" \ + " -d | --data subscriber data") + opts="s:c:p:i:t:e:d:" + optl="sub:,comm:,port:,ip:,type:,encoding:,data:" + usesparms="n" + + # Parse the command line + parseopts + + # Initialize optional fields + entity_type="1" + encoding="1" + subscriber_data="" + + # Process options + for (( i = 0; i < ${#argv[@]}; i++ )) + do + case "${argv[i]}" in + -t | --type) + i=$(( i + 1 )) + entity_type="${argv[i]}" + ;; + + -s | --sub) + i=$(( i + 1 )) + subscription_type="${argv[i]}" + ;; + + + -c | --comm) + i=$(( i + 1 )) + communication_type="${argv[i]}" + ;; + + -p | --port) + i=$(( i + 1 )) + port_number="${argv[i]}" + ;; + + -i | --ip) + i=$(( i + 1 )) + ip_address="${argv[i]}" + ;; + + -e | --encoding) + i=$(( i + 1 )) + encoding="${argv[i]}" + ;; + + -d | --data) + i=$(( i + 1 )) + subscriber_data="${argv[i]}" + ;; + esac + done + + # Build and send the request + execute $(int1 "${entity_type}") \ + $(int1 "${subscription_type}") \ + $(int1 "${communication_type}") \ + $(int4 "${port_number}") \ + $(string "${ip_address}") \ + $(int1 "${encoding}") \ + $(string "${subscriber_data}") + + # Tell user it was successful + echo "Subscription enabled" +} + +# ============================================================================= +# SMAPI Function: Asynchronous_Notification_Query_DM +# ============================================================================= +function Asynchronous_Notification_Query_DM +{ + # Define local variables + local i arraylen reclen req + local entity_type communication_type port_number ip_address + local encoding subscriber_data userid subscription_type + local notification_array_length notification_structure_length + + # Define info for parser + desc="Query current notification subscriptions" + required=() + optional=(" -t | --type entity type" \ + " : 1 = DIRECTORY" \ + " -c | --comm communication type" \ + " : 1 = TCP" \ + " : 2 = UDP" \ + " -p | --port port number" \ + " -i | --ip IP address" \ + " -e | --encoding encoding of notification" \ + " : 0 = Unspecified (defaults to 1)" \ + " : 1 = ASCII" \ + " : 2 = EBCDIC" \ + " -d | --data subscriber data") + opts="t:c:p:i:e:d:" + optl="type:,comm:,port:,ip:,encoding:,data:" + usesparms="n" + + # Parse the command line + parseopts + + # Initialize optional fields + entity_type="1" + communication_type="0" + port_number="0" + ip_address="" + encoding="0" + subscriber_data="" + + # Process options + for (( i = 0; i < ${#argv[@]}; i++ )) + do + case "${argv[i]}" in + -t | --type) + i=$(( i + 1 )) + entity_type="${argv[i]}" + ;; + + -c | --comm) + i=$(( i + 1 )) + communication_type="${argv[i]}" + ;; + + -p | --port) + i=$(( i + 1 )) + port_number="${argv[i]}" + ;; + + -i | --ip) + i=$(( i + 1 )) + ip_address="${argv[i]}" + ;; + + -e | --encoding) + i=$(( i + 1 )) + encoding="${argv[i]}" + ;; + + -d | --data) + i=$(( i + 1 )) + subscriber_data="${argv[i]}" + ;; + esac + done + + # Build and send the request + execute $(int1 "${entity_type}") \ + $(int1 "${communication_type}") \ + $(int4 "${port_number}") \ + $(string "${ip_address}") \ + $(int1 "${encoding}") \ + $(string "${subscriber_data}") + + # Retrieve the length of the returned array + get4 notification_array_length + + # Retrieve and process array entries + while [ $notification_array_length -gt 0 ] + do + # Retrieve the entry length + get4 notification_structure_length + + # Protect against empty entries + if [ $notification_structure_length -gt 0 ] + then + # Retrieve entry fields + getstring userid + get1 subscription_type + get1 communication_type + get4 port_number + getstring ip_address + get1 encoding + getstring subscriber_data + + # Convert subscription_type + case "${subscription_type}" in + 1) subscription_type="${subscription_type} (INCLUDE)" ;; + 2) subscription_type="${subscription_type} (EXCLUDE)" ;; + *) subscription_type="${subscription_type} (??)" ;; + esac + + # Convert communication_type + case "${communication_type}" in + 1) communication_type="${communication_type} (TCP)" ;; + 2) communication_type="${communication_type} (UDP)" ;; + *) communication_type="${communication_type} (??)" ;; + esac + + # Convert encoding + case "${encoding}" in + 1) encoding="${encoding} (ASCII)" ;; + 2) encoding="${encoding} (EBCDIC)" ;; + *) encoding="${encoding} (??)" ;; + esac + + # Show it to the user + echo "Subscription:" + echo " Userid: ${userid}" + echo " Subscrition type: ${subscription_type}" + echo " Communication type: ${communication_type}" + echo " Port number: ${port_number}" + echo " IP address: ${ip_address}" + echo " Encoding: ${encoding}" + echo " Subscriber data: ${subscriber_data}" + fi + + # Calculate remaining length (+4 for the "notification_structure_length" itself) + notification_array_length=$(( notification_array_length - 4 - notification_structure_length )) + done +} + +# ============================================================================= +# SMAPI Function: Authorization_List_Add +# ============================================================================= +function Authorization_List_Add +{ + # Define local variables + local i for_id function_id + + # Define info for parser + desc="Add an entry to the list of authorized users" + required=(" -f | --for image or list name for which target is authorized" \ + " -u | --func function or list name for which target is authorized") + optional=() + opts="f:u:" + optl="for:,func:" + usesparms="n" + + # Parse the command line + parseopts + + # Process options + for (( i = 0; i < ${#argv[@]}; i++ )) + do + case "${argv[i]}" in + -f | --for) + i=$(( i + 1 )) + for_id="${argv[i]}" + ;; + + -u | --func) + i=$(( i + 1 )) + function_id="${argv[i]}" + ;; + esac + done + + # Build and send the request + execute $(string "${for_id}") \ + $(string "${function_id}") + + # Tell user it was successful + echo "Authorization granted to ${smtarg} for ${for_id} and function ${function_id}" +} + +# ============================================================================= +# SMAPI Function: Authorization_List_Query +# ============================================================================= +function Authorization_List_Query +{ + # Define local variables + local i for_id function_id + local auth_record_array_length auth_record_structure_length + local requesting_userid requesting_list_indicator requesting_type + local for_userid for_list_indicator for_type + local function_name function_list_indicator function_type + + # Define info for parser + desc="Query the list of authorized users" + required=() + optional=(" -f | --for image or list name for which target is authorized" \ + " -u | --func function or list name for which target is authorized") + opts="f:u:" + optl="for:,func:" + usesparms="n" + + # Parse the command line + parseopts + + # Initialize optional fields + for_id="" + function_id="" + + # Process options + for (( i = 0; i < ${#argv[@]}; i++ )) + do + case "${argv[i]}" in + -f | --for) + i=$(( i + 1 )) + for_id="${argv[i]}" + ;; + + -u | --func) + i=$(( i + 1 )) + function_id="${argv[i]}" + ;; + esac + done + + # Build and send the request + execute $(string "${for_id}") \ + $(string "${function_id}") + + # Retrieve the length of the returned array + get4 auth_record_array_length + + # Retrieve and process array entries + while [ $auth_record_array_length -gt 0 ] + do + # Retrieve the entry length + get4 auth_record_structure_length + + # Protect against empty entries + if [ $auth_record_structure_length -gt 0 ] + then + # Retrieve entry fields + getstring requesting_userid + get1 requesting_list_indicator + getstring for_userid + get1 for_list_indicator + getstring function_name + get1 function_list_indicator + + # Convert requesting_type + requesting_type="userid" + if [ ${requesting_list_indicator} -eq 1 ] + then + requesting_type="list" + fi + + # Convert for_list_indicator + for_type="userid" + if [ ${for_list_indicator} -eq 1 ] + then + for_type="list" + fi + + # Convert function_type + function_type="name" + if [ ${function_list_indicator} -eq 1 ] + then + function_type="list" + fi + + # Show it to the user + echo "Entry:" + echo " Requesting ${requesting_type}: ${requesting_userid}" + echo " For ${for_type}: ${for_userid}" + echo " Function ${function_type}: ${function_name}" + fi + + # Calculate remaining length (+4 for the "auth_record_structure_length" itself) + auth_record_array_length=$(( auth_record_array_length - 4 - auth_record_structure_length )) + done +} + +# ============================================================================= +# SMAPI Function: Authorization_List_Remove +# ============================================================================= +function Authorization_List_Remove +{ + # Define local variables + local i for_id function_id + + # Define info for parser + desc="Remove an entry from the list of authorized users" + required=(" -f | --for image or list name for which target is authorized" \ + " -u | --func function or list name for which target is authorized") + optional=() + opts="f:u:" + optl="for:,func:" + usesparms="n" + + # Parse the command line + parseopts + + # Process options + for (( i = 0; i < ${#argv[@]}; i++ )) + do + case "${argv[i]}" in + -f | --for) + i=$(( i + 1 )) + for_id="${argv[i]}" + ;; + + -u | --func) + i=$(( i + 1 )) + function_id="${argv[i]}" + ;; + esac + done + + # Build and send the request + execute $(string "${for_id}") \ + $(string "${function_id}") + + # Tell user it was successful + echo "Authorization revoked from ${smtarg} for ${for_id} and function ${function_id}" +} + +# ============================================================================= +# SMAPI Function: Delete_ABEND_Dump +# ============================================================================= +function Delete_ABEND_Dump +{ + # Define local variables + local + + # Define info for parser + desc="Request deletion of abend dump" + + # Build and send request + execute_keywords + + # Tell user it was successful + echo "Dump deletion requested" +} + +# ============================================================================= +# SMAPI Function: Directory_Manager_Local_Tag_Define_DM +# ============================================================================= +function Directory_Manager_Local_Tag_Define_DM +{ + # Define local variables + local i tag_name tag_ordinal define_action + + # Define info for parser + desc="Define a local tag for an image" + required=(" -n | --name tag name" \ + " -o | --ordinal tag ordinal") + optional=(" -a | --action define action" \ + " : 1 = DEFINE (default)" \ + " : 2 = CHANGE") + opts="n:o:a:" + optl="name:,ordinal:,action:" + usesparms="n" + + # Parse the command line + parseopts + + # Initialize optional fields + define_action="1" + + # Process options + for (( i = 0; i < ${#argv[@]}; i++ )) + do + case "${argv[i]}" in + -n | --name) + i=$(( i + 1 )) + tag_name="${argv[i]}" + ;; + + -o | --ordinal) + i=$(( i + 1 )) + tag_ordinal="${argv[i]}" + ;; + + -a | --action) + i=$(( i + 1 )) + define_action="${argv[i]}" + ;; + esac + done + + # Build and send the request + execute $(string "${tag_name}") \ + $(int4 "${tag_ordinal}") \ + $(int1 "${define_action}") + + # Tell user it was successful + echo "Tag ${tag_name} with ${tag_ordinal} defined/changed" +} + +# ============================================================================= +# SMAPI Function: Directory_Manager_Local_Tag_Delete_DM +# ============================================================================= +function Directory_Manager_Local_Tag_Delete_DM +{ + # Define local variables + local i tag_name + + # Define info for parser + desc="Delete a local tag from an image" + required=(" -n | --name tag name") + optional=() + opts="n:" + optl="name:" + usesparms="n" + + # Parse the command line + parseopts + + # Initialize optional fields + define_action="1" + + # Process options + for (( i = 0; i < ${#argv[@]}; i++ )) + do + case "${argv[i]}" in + -n | --name) + i=$(( i + 1 )) + tag_name="${argv[i]}" + ;; + esac + done + + # Build and send the request + execute $(string "${tag_name}") + + # Tell user it was successful + echo "Tag ${tag_name} deleted" +} + +# ============================================================================= +# SMAPI Function: Directory_Manager_Local_Tag_Query_DM +# ============================================================================= +function Directory_Manager_Local_Tag_Query_DM +{ + # Define local variables + local i tag_name tag_value + + # Define info for parser + desc="Query the value of a local tag" + required=(" -n | --name tag name") + optional=() + opts="n:" + optl="name:" + usesparms="n" + + # Parse the command line + parseopts + + # Process options + for (( i = 0; i < ${#argv[@]}; i++ )) + do + case "${argv[i]}" in + -n | --name) + i=$(( i + 1 )) + tag_name="${argv[i]}" + ;; + esac + done + + # Build and send the request + execute $(string "${tag_name}") + + # Retrieve return values + getstring tag_value + + # Show them to the user + echo "Tag ${tag_name} has a value of ${tag_value}" +} + +# ============================================================================= +# SMAPI Function: Directory_Manager_Local_Tag_Set_DM +# ============================================================================= +function Directory_Manager_Local_Tag_Set_DM +{ + # Define local variables + local i tag_name tag_value + + # Define info for parser + desc="Set the value of a local tag" + required=(" -n | --name tag name" \ + " -v | --value tag value" \ + " : use \"DELETE\" to remove tag") + optional=() + opts="n:v:" + optl="name:,value:" + usesparms="n" + + # Parse the command line + parseopts + + # Process options + for (( i = 0; i < ${#argv[@]}; i++ )) + do + case "${argv[i]}" in + -n | --name) + i=$(( i + 1 )) + tag_name="${argv[i]}" + ;; + + -v | --value) + i=$(( i + 1 )) + tag_value="${argv[i]}" + ;; + esac + done + + # Build and send the request + execute $(string "${tag_name}") \ + $(string "${tag_value}") + + # Tell user it was successful + echo "Tag ${tag_name} set to ${tag_value}" +} + +# ============================================================================= +# SMAPI Function: Directory_Manager_Search_DM +# ============================================================================= +function Directory_Manager_Search_DM +{ + # Define local variables + local i search_pattern statement_array_length target_id statement + + # Define info for parser + desc="Search directory" + required=(" -p | --pattern search pattern") + optional=() + opts="p:" + optl="pattern:" + usesparms="n" + + # Parse the command line + parseopts + + # Process options + for (( i = 0; i < ${#argv[@]}; i++ )) + do + case "${argv[i]}" in + -p | --pattern) + i=$(( i + 1 )) + search_pattern="${argv[i]}" + ;; + esac + done + + # Build and send the request + execute $(string "${search_pattern}") + + # Retrieve the length of the returned array +# get4 statement_array_length + + # Retrieve and process array entries +# while [ ${#resp} -gt 0 ] +# do +# getstring target_id +# getstring statement +# +# printf "%-8s: %s\n" "${target_id}" "${statement}" +# done + getstringarray statement_array + for (( i = 0; i < ${#statement_array[@]}; i += 2 )) + do + image_name=${statement_array[i]} + statement=${statement_array[$(( i + 1 ))]} + printf "%-8s: %s\n" "${image_name}" "${statement}" + done +} + +# ============================================================================= +# SMAPI Function: Event_Stream_Add +# ============================================================================= +function Event_Stream_Add +{ + # Define local variables + local i operation_id + + # Define info for parser + desc="Cancel asynchronous task" + required=(" -o | --opid operation id") + optional=() + opts="o:" + optl="opid:" + usesparms="n" + + # Parse the command line + parseopts + + # Process options + for (( i = 0; i < ${#argv[@]}; i++ )) + do + case "${argv[i]}" in + -o | --opid) + i=$(( i + 1 )) + operation_id="${argv[i]}" + ;; + esac + done + + # Build and send the request + execute $(int4 "${operation_id}") + + # Tell user it was successful + echo "Task ${operation_id} cancelled" +} + +# ============================================================================= +# SMAPI Function: Event_Subscribe +# ============================================================================= +function Event_Subscribe +{ + # Define local variables + local i match_key + + # Define info for parser + desc="Request deletion of abend dump" + required=() + optional=(" -m | --match exact or fuzzy key to match") + opts="m:" + optl="match:" + usesparms="n" + + # Parse the command line + parseopts + + # Initialize optional fields + match_key="" + + # Process options + for (( i = 0; i < ${#argv[@]}; i++ )) + do + case "${argv[i]}" in + -m | --match) + i=$(( i + 1 )) + match_key="${argv[i]}" + ;; + esac + done + + # Build and send the request + execute $(int4 "${match_key}") + + # Tell user it was successful + echo "Subscribed to event" +} + +# ============================================================================= +# SMAPI Function: Event_Unsubscribe +# ============================================================================= +function Event_Unsubscribe +{ + # Define local variables + local + + # Define info for parser + desc="Unsubscribe from events" + required=() + optional=() + opts="" + optl="" + usesparms="n" + + # Parse the command line + parseopts + + # Build and send the request + execute + + # Tell user it was successful + echo "Unsubscribed from events" +} + +# ============================================================================= +# SMAPI Function: Directory_Manager_Task_Cancel_DM +# ============================================================================= +function Directory_Manager_Task_Cancel_DM +{ + # Define local variables + local i operation_id + + # Define info for parser + desc="Cancel asynchronous task" + required=(" -o | --opid operation id") + optional=() + opts="o:" + optl="opid:" + usesparms="n" + + # Parse the command line + parseopts + + # Process options + for (( i = 0; i < ${#argv[@]}; i++ )) + do + case "${argv[i]}" in + -o | --opid) + i=$(( i + 1 )) + operation_id="${argv[i]}" + ;; + esac + done + + # Build and send the request + execute $(int4 "${operation_id}") + + # Tell user it was successful + echo "Task ${operation_id} cancelled" +} + +# ============================================================================= +# SMAPI Function: Image_Activate +# ============================================================================= +function Image_Activate +{ + # Define local variables + local activated not_activated image_name + local failing_array_length failing_structure_length + + # Define info for parser + desc="Activate image(s)" + required=() + optional=() + opts="" + optl="" + usesparms="n" + + # Parse the command line + parseopts + + # Build and send the request + execute_no_check + + # It was partially successful...show user what didn't activate + if [ ${retc} -eq 200 -a ${reas} -eq 28 ] + then + # Retrieve the return values + get4 activated + get4 not_activated + + # Show them to the user + echo "Number of images activated: ${activated}" + echo "Number of images not activated: ${not_activated}" + + # Retrieve the length of the returned array + get4 failing_array_length + + # Retrieve and process array entries + while [ $failing_array_length -gt 0 ] + do + # Retrieve the entry length + get4 failing_structure_length + + # Protect against empty entries + if [ $failing_structure_length -gt 0 ] + then + # Retrieve the entry fields + getstring image_name + get4 retr + get4 reas + + # Tell the user why this one failed + echo "Activation of ${image_name} failed due to: " + showerror + echo + fi + + # Calculate remaining length (+4 for the "failing_structure_length" itself) + failing_array_length=$(( failing_array_length - 4 - failing_structure_length )) + done + + # Bail since we handled this error specifically + return + fi + + # Check for error + checkandfail + + # Tell user it was successful + echo "${smtarg} activated" +} + +# ============================================================================= +# SMAPI Function: Image_Active_Configuration_Query +# ============================================================================= +function Image_Active_Configuration_Query +{ + # Define local variables + local memory_size memory_unit share_type share_value number_CPUs + local CPU_info_array_length CPU_info_structure_length + local CPU_number CPU_id CPU_status + local device_info_array_length device_info_array_length + local device_type device_address + + # Define info for parser + desc="Query active configuration for target" + required=() + optional=() + opts="" + optl="" + usesparms="n" + + # Parse the command line + parseopts + + # Build and send the request + execute + + # Retrieve return values + get4 memory_size + get1 memory_unit + get1 share_type + getstring share_value + get4 number_CPUs + + # Convert memory_unit + case "${memory_unit}" in + 1) memory_unit="${memory_unit} (KB)" ;; + 2) memory_unit="${memory_unit} (MB)" ;; + 3) memory_unit="${memory_unit} (GB)" ;; + *) memory_unit="${memory_unit} (??)" ;; + esac + + # Convert share_type + percent="" + case "${share_type}" in + 1) share_type="${share_type} (Relative)" ;; + 2) share_type="${share_type} (Absolute)" ;; + *) share_type="${share_type} (??)" ;; + esac + + # Show the user + echo "Memory size: ${memory_size}" + echo "Memory units: ${memory_unit}" + echo "Share type: ${share_type}" + echo "Share value: ${share_value}" + echo "CPU count: ${number_CPUs}" + echo + + # Retrieve the length of the returned array + get4 CPU_info_array_length + + # Retrieve and process array entries + echo "CPUs:" + while [ $CPU_info_array_length -gt 0 ] + do + # Retrieve the entry length + get4 CPU_info_structure_length + + # Protect against empty entries + if [ $CPU_info_structure_length -gt 0 ] + then + # Retrieve the entry fields + get4 CPU_number + getstring CPU_id + get1 CPU_status + + # Convert CPU_status + case "${CPU_status}" in + 1) CPU_status="${CPU_status} (Base)" ;; + 2) CPU_status="${CPU_status} (Stopped)" ;; + 3) CPU_status="${CPU_status} (Check-stopped)" ;; + 4) CPU_status="${CPU_status} (Non-base, active)" ;; + *) CPU_status="${CPU_status} (??)" ;; + esac + + # Show the user + echo " Address: ${CPU_number}" + echo " ID: ${CPU_id}" + echo " Status: ${CPU_status}" + echo + fi + + # Calculate remaining length (+4 for the "CPU_info_structure_length" itself) + CPU_info_array_length=$(( CPU_info_array_length - 4 - CPU_info_structure_length )) + done + + # Retrieve the length of the returned array + get4 device_info_array_length + + # Retrieve and process array entries + echo "Devices:" + while [ $device_info_array_length -gt 0 ] + do + # Retrieve the entry length + get4 device_info_structure_length + + # Protect against empty entries + if [ $device_info_structure_length -gt 0 ] + then + # Retrieve the entry fields + get1 device_type + getstring device_address + + # Convert device_type + case "${device_type}" in + 1) device_type="${device_type} (CONS)" ;; + 2) device_type="${device_type} (RDR)" ;; + 3) device_type="${device_type} (PUN)" ;; + 4) device_type="${device_type} (PRT)" ;; + 5) device_type="${device_type} (DASD)" ;; + *) device_type="${device_type} (??)" ;; + esac + + # Show the user + echo " Device ${device_address} is ${device_type}" + fi + + # Calculate remaining length (+4 for the "device_info_structure_length" itself) + device_info_array_length=$(( device_info_array_length - 4 - device_info_structure_length )) + done +} + +# ============================================================================= +# SMAPI Function: Image_CPU_Define +# ============================================================================= +function Image_CPU_Define +{ + # Define local variables + local i cpu_address cpu_type + + # Define info for parser + desc="Add a CPU to an active image" + required=(" -a | --addr CPU address") + optional=(" -t | --type CPU type" \ + " : 0 = Unspecifed (default)" \ + " : 1 = CP" \ + " : 2 = IFL" \ + " : 3 = ZAAP" \ + " : 4 = ZIIP") + opts="a:t:" + optl="addr:,type" + usesparms="n" + + # Parse the command line + parseopts + + # Initialize optional fields + cpu_type="0" + + # Process options + for (( i = 0; i < ${#argv[@]}; i++ )) + do + case "${argv[i]}" in + -a | --addr) + i=$(( i + 1 )) + cpu_address="${argv[i]}" + ;; + + -t | --type) + i=$(( i + 1 )) + cpu_type="${argv[i]}" + ;; + esac + done + + # Build and send the request + execute $(string "${cpu_address}") \ + $(int1 "${cpu_type}") + + # Tell user it was successful + echo "CPU ${cpu_address} added to active ${smtarg}" +} + +# ============================================================================= +# SMAPI Function: Image_CPU_Define_DM +# ============================================================================= +function Image_CPU_Define_DM +{ + # Define local variables + local i cpu_address base_cpu cpuid dedicate_cpu + + # Define info for parser + desc="Add a CPU to image directory" + required=(" -a | --addr CPU address" \ + " -c | --cpuid CPU id number") + optional=(" -b | --base base CPU" \ + " : 0 = Unspecified (default)" \ + " : 1 = BASE" \ + " -d | --dedicate dedicate real proc" \ + " : 0 = Unspecified (default)" \ + " : 1 = NODEDICATE" \ + " : 2 = DEDICATE") + opts="a:c:b:d:" + optl="addr:,cpuid:,base:,dedicate:" + usesparms="n" + + # Parse the command line + parseopts + + # Initialize optional fields + base_cpu="0" + dedicate_cpu="0" + + # Process options + for (( i = 0; i < ${#argv[@]}; i++ )) + do + case "${argv[i]}" in + -a | --addr) + i=$(( i + 1 )) + cpu_address="${argv[i]}" + ;; + + -c | --cpuid) + i=$(( i + 1 )) + cpuid="${argv[i]}" + ;; + + -b | --base) + i=$(( i + 1 )) + base_cpu="${argv[i]}" + ;; + + -d | --dedicate) + i=$(( i + 1 )) + dedicate_cpu="${argv[i]}" + ;; + esac + done + + # Build and send the request + execute $(string "${cpu_address}") \ + $(int1 "${base_cpu}") \ + $(string "${cpuid}") \ + $(int1 "${dedicate_cpu}") \ + $(int1 "0") + + # Tell user it was successful + echo "CPU ${cpu_address} added to ${smtarg}" +} + +# ============================================================================= +# SMAPI Function: Image_CPU_Delete +# ============================================================================= +function Image_CPU_Delete +{ + # Define local variables + local i cpu_address + + # Define info for parser + desc="Delete a CPU from active image" + required=(" -a | --addr CPU address") + optional=() + opts="a:" + optl="addr:" + usesparms="n" + + # Parse the command line + parseopts + + # Process options + for (( i = 0; i < ${#argv[@]}; i++ )) + do + case "${argv[i]}" in + -a | --addr) + i=$(( i + 1 )) + cpu_address="${argv[i]}" + ;; + esac + done + + # Build and send the request + execute $(string "${cpu_address}") + + # Tell user it was successful + echo "CPU ${cpu_address} deleted from active ${smtarg}" +} + +# ============================================================================= +# SMAPI Function: Image_CPU_Delete_DM +# ============================================================================= +function Image_CPU_Delete_DM +{ + # Define local variables + local i cpu_address + + # Define info for parser + desc="Delete a CPU from image directory" + required=(" -a | --addr CPU address") + optional=() + opts="a:" + optl="addr:" + usesparms="n" + + # Parse the command line + parseopts + + # Process options + for (( i = 0; i < ${#argv[@]}; i++ )) + do + case "${argv[i]}" in + -a | --addr) + i=$(( i + 1 )) + cpu_address="${argv[i]}" + ;; + esac + done + + # Build and send the request + execute $(string "${cpu_address}") + + # Tell user it was successful + echo "CPU ${cpu_address} deleted from ${smtarg}" +} + +# ============================================================================= +# SMAPI Function: Image_CPU_Query +# ============================================================================= +function Image_CPU_Query +{ + # Define local variables + local CPU_info_array_length CPU_info_structure_length + local number_CPUs CPU_address CPU_id CPU_base CPU_status CPU_type + + # Define info for parser + desc="Query CPUs in active image" + required=() + optional=() + opts="" + optl="" + usesparms="n" + + # Parse the command line + parseopts + + # Build and send the request + execute + + # Retrieve return values + get4 number_CPUs + + # Show the user + echo "CPU count: ${number_CPUs}" + echo + + # Retrieve the length of the returned array + get4 CPU_info_array_length + + # Retrieve and process array entries + echo "CPUs:" + while [ $CPU_info_array_length -gt 0 ] + do + # Retrieve the entry length + get4 CPU_info_structure_length + + # Protect against empty entries + if [ $CPU_info_structure_length -gt 0 ] + then + # Retrieve the entry fields + get4 CPU_address + getstring CPU_id + get1 CPU_base + get1 CPU_status + get1 CPU_type + + # Convert CPU_base + case "${CPU_base}" in + 0) CPU_base="${CPU_base} (Unspecified}" ;; + 1) CPU_base="${CPU_base} (BASE)" ;; + 2) CPU_base="${CPU_base} (non-BASE)" ;; + *) CPU_base="${CPU_base} (??)" ;; + esac + + # Convert CPU_status + case "${CPU_status}" in + 1) CPU_status="${CPU_status} (Stopped)" ;; + 2) CPU_status="${CPU_status} (Check-stopped)" ;; + 3) CPU_status="${CPU_status} (Soft-stopped or active)" ;; + *) CPU_status="${CPU_status} (??)" ;; + esac + + # Convert CPU_type + case "${CPU_type}" in + 1) CPU_type="${CPU_type} (CP)" ;; + 2) CPU_type="${CPU_type} (IFL)" ;; + 3) CPU_type="${CPU_type} (ZAAP)" ;; + 4) CPU_type="${CPU_type} (ZIIP)" ;; + *) CPU_type="${CPU_type} (??)" ;; + esac + + # Show the user + echo " Address: ${CPU_address}" + echo " ID: ${CPU_id}" + echo " Base: ${CPU_base}" + echo " Type: ${CPU_type}" + echo " Status: ${CPU_status}" + echo + fi + + # Calculate remaining length (+4 for the "CPU_info_structure_length" itself) + CPU_info_array_length=$(( CPU_info_array_length - 4 - CPU_info_structure_length )) + done +} + +# ============================================================================= +# SMAPI Function: Image_CPU_Query_DM +# ============================================================================= +function Image_CPU_Query_DM +{ + # Define local variables + local i cpu_address base_cpu cpuid dedicate_cpu crypto + + # Define info for parser + desc="Query CPUs in image directory" + required=(" -a | --addr CPU address") + optional=() + opts="a:" + optl="addr:" + usesparms="n" + + # Parse the command line + parseopts + + # Process options + for (( i = 0; i < ${#argv[@]}; i++ )) + do + case "${argv[i]}" in + -a | --addr) + i=$(( i + 1 )) + cpu_address="${argv[i]}" + ;; + esac + done + + # Build and send the request + execute $(string "${cpu_address}") + + # Retrieve return values + getstring cpu_address + get1 base_cpu + getstring cpuid + get1 dedicate_cpu + get1 crypto + + # Convert base_cpu + case "${base_cpu}" in + 0) base_cpu="${base_cpu} (unspecified)" ;; + 1) base_cpu="${base_cpu} (BASE)" ;; + *) base_cpu="${base_cpu} (??)" ;; + esac + + # Convert dedicate_cpu + case "${dedicate_cpu}" in + 0) dedicate_cpu="${dedicate_cpu} (unspecified)" ;; + 1) dedicate_cpu="${dedicate_cpu} (NODEDICATE)" ;; + 2) dedicate_cpu="${dedicate_cpu} (DEDICATE)" ;; + *) dedicate_cpu="${dedicate_cpu} (??)" ;; + esac + + # Show the user + echo " Address: ${cpu_address}" + echo " ID: ${cpuid}" + echo " Base: ${base_cpu}" + echo " Dedicate: ${dedicate_cpu}" + echo +} + +# ============================================================================= +# SMAPI Function: Image_CPU_Set_Maximum_DM +# ============================================================================= +function Image_CPU_Set_Maximum_DM +{ + # Define local variables + local i max_cpu + + # Define info for parser + desc="Set the maximum number of CPUs for an image" + required=(" -m | --max CPU address") + optional=() + opts="m:" + optl="max:" + usesparms="n" + + # Parse the command line + parseopts + + # Process options + for (( i = 0; i < ${#argv[@]}; i++ )) + do + case "${argv[i]}" in + -m | --max) + i=$(( i + 1 )) + max_cpu="${argv[i]}" + ;; + esac + done + + # Build and send the request + execute $(int4 "${max_cpu}") + + # Tell user it was successful + echo "Maximum CPU count set to ${max_cpu} for ${smtarg}" +} + +# ============================================================================= +# SMAPI Function: Image_Create_DM +# ============================================================================= +function Image_Create_DM +{ + # Define local variables + local i file type_name initial_password initial_account_number + local image_record_array + + # Define info for parser + desc="Create image" + required=() + optional=(" -n | --name name of prototype used as model" \ + " -p | --pass the initial password" \ + " -a | --acct the initial account number") + opts="n:p:a:" + optl="name:,pass:,acct:" + usesparms="n" + + # Parse the command line + parseopts + + # Initialize optional fields + prototype_name="" + initial_password="" + initial_account_number="" + + # Process options + for (( i = 0; i < ${#argv[@]}; i++ )) + do + case "${argv[i]}" in + -n | --name) + i=$(( i + 1 )) + prototype_name="${argv[i]}" + ;; + + -p | --pass) + i=$(( i + 1 )) + initial_password="${argv[i]}" + ;; + + -a | --acct) + i=$(( i + 1 )) + initial_account_number="${argv[i]}" + ;; + esac + done + + # Load array from stdin + loadarray image_record_array + + # Build and send the request + execute $(string "${prototype_name}") \ + $(string "${initial_password}") \ + $(string "${initial_account_number}") \ + $(stringarray "${image_record_array[@]}") + + # Tell user it was successful + echo "${smtarg} created" +} + +# ============================================================================= +# SMAPI Function: Image_Deactivate +# ============================================================================= +function Image_Deactivate +{ + # Define local variables + local i force_time deactivated not_deactivated image_name + local failing_array_length failing_structure_length + + # Define info for parser + desc="Deactivate image(s)" + required=() + optional=(" -t | --time when deactivation should occur" \ + " : IMMED" \ + " : WITHIN seconds" \ + " : BY hh:mm" \ + " : BY hh:mm:ss") + + opts="t:" + optl="time:" + usesparms="n" + + # Parse the command line + parseopts + + # Initialize optional fields + force_time="" + + # Process options + for (( i = 0; i < ${#argv[@]}; i++ )) + do + case "${argv[i]}" in + -t | --time) + i=$(( i + 1 )) + force_time="${argv[i]}" + ;; + esac + done + + # Build and send the request + execute_no_check $(string "${force_time}") + + # It was partially successful...show user what didn't deactivate + if [ ${retc} -eq 200 -a ${reas} -eq 28 ] + then + # Retrieve the return values + get4 deactivated + get4 not_deactivated + + # Show them to the user + echo "Number of images deactivated: ${deactivated}" + echo "Number of images not deactivated: ${not_deactivated}" + + # Retrieve the length of the returned array + get4 failing_array_length + + # Retrieve and process array entries + while [ $failing_array_length -gt 0 ] + do + # Retrieve the entry length + get4 failing_structure_length + + # Protect against empty entries + if [ $failing_structure_length -gt 0 ] + then + # Retrieve the entry fields + getstring image_name + get4 retr + get4 reas + + # Tell the user why this one failed + echo "Activation of ${image_name} failed due to: " + showerror + echo + fi + + # Calculate remaining length (+4 for the "failing_structure_length" itself) + failing_array_length=$(( failing_array_length - 4 - failing_structure_length )) + done + + # Bail since we handled this error specifically + return + # Suppress error message if deactived with N seconds + elif [ ${retc} -ne 0 ] + then + # Check for error + checkandfail + fi + + # Tell user it was successful + echo "${smtarg} deactivated" +} + +# ============================================================================= +# SMAPI Function: Image_Definition_Async_Updates +# ============================================================================= +function Image_Definition_Async_Updates +{ + # Define local variables + local + + # Define info for parser + desc="Enable/disable async image updates" + + # Build and send the request + execute_keywords + + # Tell user it was successful + echo "Entry added for ${smtarg}" +} + +# ============================================================================= +# SMAPI Function: Image_Definition_Create_DM +# ============================================================================= +function Image_Definition_Create_DM +{ + # Define local variables + local + + # Define info for parser + desc="Create new virtual machine entry" + required=() + optional=() + opts="" + optl="" + usesparms="o" + + # Parse the command line + parseopts + + # Complain if no additional parms were specified + if [ -z "${addparms}" ] + then + echo "Additional parameters not specified" + exit 1 + fi + + # Build and send the request + execute $(int4 $(( ${#addparms} / 2 ))) \ + ${addparms} + + # Tell user it was successful + echo "Entry added for ${smtarg}" +} + +# ============================================================================= +# SMAPI Function: Image_Definition_Delete_DM +# ============================================================================= +function Image_Definition_Delete_DM +{ + # Define local variables + local + + # Define info for parser + desc="Delete virtual machine info" + required=() + optional=() + opts="" + optl="" + usesparms="o" + + # Parse the command line + parseopts + + # Complain if no additional parms were specified + if [ -z "${addparms}" ] + then + echo "Additional parameters not specified" + exit 1 + fi + + # Build and send the request + execute $(int4 $(( ${#addparms} / 2 ))) \ + ${addparms} + + # Tell user it was successful + echo "Info deleted from ${smtarg}" +} + +# ============================================================================= +# SMAPI Function: Image_Definition_Query_DM +# ============================================================================= +function Image_Definition_Query_DM +{ + # Define local variables + local + + # Define info for parser + desc="Extract directory records" + required=() + optional=() + opts="" + optl="" + usesparms="o" + + # Parse the command line + parseopts + + # Complain if no additional parms were specified + if [ -z "${addparms}" ] + then + echo "Additional parameters not specified" + exit 1 + fi + + # Build and send the request + execute_no_check $(int4 $(( ${#addparms} / 2 ))) \ + ${addparms} + + # Retrieve return values + if [ ${retc} -eq 0 -a ${reas} -eq 0 ] + then + get4 directory_information_length + showasciizarray ${directory_information_length} + elif [ ${retc} -eq 8 -a ${reas} -eq 3002 ] + then + getstring error_data + echo "error:" ${error_data} + else + checkandfail + fi +} + +# ============================================================================= +# SMAPI Function: Image_Definition_Update_DM +# ============================================================================= +function Image_Definition_Update_DM +{ + # Define local variables + local + + # Define info for parser + desc="Update virtual machine entry" + required=() + optional=() + opts="" + optl="" + usesparms="o" + + # Parse the command line + parseopts + + # Complain if no additional parms were specified + if [ -z "${addparms}" ] + then + echo "Additional parameters not specified" + exit 1 + fi + + # Build and send the request + execute $(int4 $(( ${#addparms} / 2 ))) \ + ${addparms} + + # Tell user it was successful + echo "Entry updated for ${smtarg}" +} + +# ============================================================================= +# SMAPI Function: Image_Delete_DM +# ============================================================================= +function Image_Delete_DM +{ + # Define local variables + local i data_security_erase + + # Define info for parser + desc="Delete image" + required=() + optional=(" -e | --erase erase disks" \ + " : 0 = Unspecified (use system default)" \ + " : 1 = Do not erase" \ + " : 2 = Erase") + opts="e:" + optl="erase:" + usesparms="n" + + # Parse the command line + parseopts + + # Initialize optional fields + data_security_erase="0" + + # Process options + for (( i = 0; i < ${#argv[@]}; i++ )) + do + case "${argv[i]}" in + -e | --erase) + i=$(( i + 1 )) + data_security_erase="${argv[i]}" + ;; + esac + done + + # Build and send the request + execute $(int1 "${data_security_erase}") + + # Tell user it was successful + echo "${smtarg} image deleted" +} + +# ============================================================================= +# SMAPI Function: Image_Device_Dedicate +# ============================================================================= +function Image_Device_Dedicate +{ + # Define local variables + local i image_device_number real_device_number readonly + + # Define info for parser + desc="Add a dedicated device to active image" + required=(" -a | --addr virtual address of device" \ + " -d | --dev real address of device") + optional=(" -r | --readonly read-only mode" \ + " : 0 = not read-only" \ + " : 1 = read-only mode") + opts="a:d:r:" + optl="addr:,dev:,readonly" + usesparms="n" + + # Parse the command line + parseopts + + # Initialize optional fields + readonly="0" + + # Process options + for (( i = 0; i < ${#argv[@]}; i++ )) + do + case "${argv[i]}" in + -a | --addr) + i=$(( i + 1 )) + image_device_number="${argv[i]}" + ;; + + -d | --dev) + i=$(( i + 1 )) + real_device_number="${argv[i]}" + ;; + + -r | --readonly) + i=$(( i + 1 )) + readonly="${argv[i]}" + ;; + esac + done + + # Build and send the request + execute $(string "${image_device_number}") \ + $(string "${real_device_number}") \ + $(int1 "${readonly}") + + # Tell user it was successful + echo "${real_device_number} dedicated to active ${smtarg} as ${image_device_number}" +} + +# ============================================================================= +# SMAPI Function: Image_Device_Dedicate_DM +# ============================================================================= +function Image_Device_Dedicate_DM +{ + # Define local variables + local i image_device_number real_device_number readonly + + # Define info for parser + desc="Add a dedicated device to image" + required=(" -a | --addr virtual address of device" \ + " -d | --dev real address of device") + optional=(" -r | --readonly read-only mode" \ + " : 0 = not read-only" \ + " : 1 = read-only mode") + opts="a:d:r:" + optl="addr:,dev:,readonly" + usesparms="n" + + # Parse the command line + parseopts + + # Initialize optional fields + readonly="0" + + # Process options + for (( i = 0; i < ${#argv[@]}; i++ )) + do + case "${argv[i]}" in + -a | --addr) + i=$(( i + 1 )) + image_device_number="${argv[i]}" + ;; + + -d | --dev) + i=$(( i + 1 )) + real_device_number="${argv[i]}" + ;; + + -r | --readonly) + i=$(( i + 1 )) + readonly="${argv[i]}" + ;; + esac + done + + # Build and send the request + execute $(string "${image_device_number}") \ + $(string "${real_device_number}") \ + $(int1 "${readonly}") + + # Tell user it was successful + echo "${real_device_number} dedicated to ${smtarg} as ${image_device_number}" +} + +# ============================================================================= +# SMAPI Function: Image_Device_Reset +# ============================================================================= +function Image_Device_Reset +{ + # Define local variables + local i image_device_number + + # Define info for parser + desc="Clear pending interrupts from device dedicated to active image" + required=(" -a | --addr virtual address of device") + optional=() + opts="a:" + optl="addr:" + usesparms="n" + + # Parse the command line + parseopts + + # Process options + for (( i = 0; i < ${#argv[@]}; i++ )) + do + case "${argv[i]}" in + -a | --addr) + i=$(( i + 1 )) + image_device_number="${argv[i]}" + ;; + esac + done + + # Build and send the request + execute $(string "${image_device_number}") + + # Tell user it was successful + echo "${smtarg}'s ${image_device_number} reset" +} + +# ============================================================================= +# SMAPI Function: Image_Device_Undedicate +# ============================================================================= +function Image_Device_Undedicate +{ + # Define local variables + local i image_device_number + + # Define info for parser + desc="Remove a dedicated device from active image" + required=(" -a | --addr virtual address of device") + optional=() + opts="a:" + optl="addr:" + usesparms="n" + + # Parse the command line + parseopts + + # Process options + for (( i = 0; i < ${#argv[@]}; i++ )) + do + case "${argv[i]}" in + -a | --addr) + i=$(( i + 1 )) + image_device_number="${argv[i]}" + ;; + esac + done + + # Build and send the request + execute $(string "${image_device_number}") + + # Tell user it was successful + echo "${image_device_number} undedicated from ${smtarg}" +} + +# ============================================================================= +# SMAPI Function: Image_Device_Undedicate_DM +# ============================================================================= +function Image_Device_Undedicate_DM +{ + # Define local variables + local i image_device_number + + # Define info for parser + desc="Remove a dedicated device from image" + required=(" -a | --addr virtual address of device") + optional=() + opts="a:" + optl="addr:" + usesparms="n" + + # Parse the command line + parseopts + + # Process options + for (( i = 0; i < ${#argv[@]}; i++ )) + do + case "${argv[i]}" in + -a | --addr) + i=$(( i + 1 )) + image_device_number="${argv[i]}" + ;; + esac + done + + # Build and send the request + execute $(string "${image_device_number}") + + # Tell user it was successful + echo "${image_device_number} undedicated from ${smtarg}" +} + +# ============================================================================= +# SMAPI Function: Image_Disk_Copy +# ============================================================================= +function Image_Disk_Copy +{ + # Define local variables + local i image_disk_number + + # Define info for parser + desc="Clone a disk in active image" + required=(" -a | --addr address of disk") + optional=() + opts="a:" + optl="addr:" + usesparms="n" + + # Parse the command line + parseopts + + # Process options + for (( i = 0; i < ${#argv[@]}; i++ )) + do + case "${argv[i]}" in + -a | --addr) + i=$(( i + 1 )) + image_disk_number="${argv[i]}" + ;; + esac + done + + # Build and send the request + execute $(string "${image_disk_number}") + + # Tell user it was successful + echo "${image_disk_number} disk cloned in active ${smtarg}" +} + +# ============================================================================= +# SMAPI Function: Image_Disk_Copy_DM +# ============================================================================= +function Image_Disk_Copy_DM +{ + # Define local variables + local i image_disk_number source_image_name source_image_disk_number + local image_disk_allocation_type allocation_area_name_or_volser + local image_disk_mode read_password write_password multi_password + + # Define info for parser + desc="Clone a disk in image" + required=(" -a | --addr address of disk" \ + " -s | --srcname source image name" \ + " -d | --srcdisk source disk" \ + " -t | --alctype allocation type" \ + " : nnn = starting cylinder or block" \ + " : AUTOG = automatic group" \ + " : AUTOR = automatic region" \ + " : AUTOV = automatic volume" \ + " : DEVNO = full volume midisk" \ + " -n | --name allocation area name or volser" \ + " -m | --mode disk mode") + optional=(" -r | --read read password" \ + " -w | --write write password" \ + " -i | --multi multi password") + opts="a:s:d:t:n:m:r:w:i:" + optl="addr:,srcname:,srcdisk:,alctype:,name:,mode:,read:,write:,multi:" + usesparms="n" + + # Parse the command line + parseopts + + # Initialize optional variables + read_password="" + write_password="" + multi_password="" + + # Process options + for (( i = 0; i < ${#argv[@]}; i++ )) + do + case "${argv[i]}" in + -a | --addr) + i=$(( i + 1 )) + image_disk_number="${argv[i]}" + ;; + + -s | --srcname) + i=$(( i + 1 )) + source_image_name="${argv[i]}" + ;; + + -d | --srcdisk) + i=$(( i + 1 )) + source_image_disk_number="${argv[i]}" + ;; + + -t | --alctype) + i=$(( i + 1 )) + image_disk_allocation_type="${argv[i]}" + ;; + + -n | --name) + i=$(( i + 1 )) + allocation_area_name_or_volser="${argv[i]}" + ;; + + -m | --mode) + i=$(( i + 1 )) + image_disk_mode="${argv[i]}" + ;; + + -r | --read) + i=$(( i + 1 )) + read_password="${argv[i]}" + ;; + + -w | --write) + i=$(( i + 1 )) + write_password="${argv[i]}" + ;; + + -i | --multi) + i=$(( i + 1 )) + multi_password="${argv[i]}" + ;; + esac + done + + # Build and send the request + execute $(string "${image_disk_number}") \ + $(string "${source_image_name}") \ + $(string "${source_image_disk_number}") \ + $(string "${image_disk_allocation_type}") \ + $(string "${allocation_area_name_or_volser}") \ + $(string "${image_disk_mode}") \ + $(string "${read_password}") \ + $(string "${write_password}") \ + $(string "${multi_password}") + + # Tell user it was successful + echo "${source_image_name} ${source_image_disk_number} disk copied to ${smtarg} ${image_disk_number}" +} + +# ============================================================================= +# SMAPI Function: Image_Disk_Create +# ============================================================================= +function Image_Disk_Create +{ + # Define local variables + local i image_disk_number image_disk_mode + + # Define info for parser + desc="Add a disk to an active image" + required=(" -a | --addr address of disk") + optional=(" -m | --mode access mode") + opts="a:m:" + optl="addr:,mode:" + usesparms="n" + + # Parse the command line + parseopts + + # Initialize optional variables + image_disk_mode="" + + # Process options + for (( i = 0; i < ${#argv[@]}; i++ )) + do + case "${argv[i]}" in + -a | --addr) + i=$(( i + 1 )) + image_disk_number="${argv[i]}" + ;; + + -m | --mode) + i=$(( i + 1 )) + image_disk_mode="${argv[i]}" + ;; + esac + done + + # Build and send the request + execute $(string "${image_disk_number}") \ + $(string "${image_disk_mode}") + + # Tell user it was successful + echo "${image_disk_number} added to active ${smtarg}" +} + +# ============================================================================= +# SMAPI Function: Image_Disk_Create_DM +# ============================================================================= +function Image_Disk_Create_DM +{ + # Define local variables + local i image_disk_number image_disk_device_type image_disk_allocation_type + local allocation_area_name_or_volser allocation_unit_size image_disk_size + local image_disk_mode image_disk_formatting image_disk_label + local read_password write_password multi_password + + # Define info for parser + desc="Add a disk to image" + required=(" -a | --addr address of disk" \ + " -d | --devtype device type" \ + " -t | --alctype allocation type" \ + " : nnn = starting cylinder or block" \ + " : AUTOG = automatic group" \ + " : AUTOR = automatic region" \ + " : AUTOV = automatic volume" \ + " : DEVNO = full volume midisk" \ + " : T-DISK = automatic temporary disk" \ + " : V-DISK = automatic virtual disk" \ + " -n | --name allocation area name or volser" \ + " -u | --units allocation unit size" \ + " : 1 = cylinders" \ + " : 2 = BLK0512" \ + " : 3 = BLK1024" \ + " : 4 = BLK2048" \ + " : 5 = BLK4096" \ + " -s | --size disk size (use 0 for DEVNO type)" \ + " -m | --mode disk mode") + optional=(" -f | --format format disk after allocation" \ + " : 0 = Unspecified" \ + " : (CMS if \"--label\" used else NONE)" \ + " : 1 = NONE" \ + " : 2 = CMS0512" \ + " : 3 = CMS1024" \ + " : 4 = CMS2048" \ + " : 5 = CMS4096" \ + " : 6 = CMS - default block size" \ + " -l | --label disk label" \ + " -r | --read read password" \ + " -w | --write write password" \ + " -i | --multi multi password") + opts="a:d:t:n:u:s:m:f:l:r:w:i:" + optl="addr:,devtype:,alctype:,name:,units:,size:,mode:,format:,label:,read:,write:,multi:" + usesparms="n" + + # Parse the command line + parseopts + + # Initialize optional variables + image_disk_formatting="0" + image_disk_label="" + read_password="" + write_password="" + multi_password="" + + # Process options + for (( i = 0; i < ${#argv[@]}; i++ )) + do + case "${argv[i]}" in + -a | --addr) + i=$(( i + 1 )) + image_disk_number="${argv[i]}" + ;; + + -d | --devtype) + i=$(( i + 1 )) + image_disk_device_type="${argv[i]}" + ;; + + -t | --alctype) + i=$(( i + 1 )) + image_disk_allocation_type="${argv[i]}" + ;; + + -n | --name) + i=$(( i + 1 )) + allocation_area_name_or_volser="${argv[i]}" + ;; + + -u | --units) + i=$(( i + 1 )) + allocation_unit_size="${argv[i]}" + ;; + + -s | --size) + i=$(( i + 1 )) + image_disk_size="${argv[i]}" + ;; + + -m | --mode) + i=$(( i + 1 )) + image_disk_mode="${argv[i]}" + ;; + + -f | --format) + i=$(( i + 1 )) + image_disk_formatting="${argv[i]}" + ;; + + -l | --label) + i=$(( i + 1 )) + image_disk_label="${argv[i]}" + ;; + + -r | --read) + i=$(( i + 1 )) + read_password="${argv[i]}" + ;; + + -w | --write) + i=$(( i + 1 )) + write_password="${argv[i]}" + ;; + + -i | --multi) + i=$(( i + 1 )) + multi_password="${argv[i]}" + ;; + esac + done + + # Build and send the request + execute $(string "${image_disk_number}") \ + $(string "${image_disk_device_type}") \ + $(string "${image_disk_allocation_type}") \ + $(string "${allocation_area_name_or_volser}") \ + $(int1 "${allocation_unit_size}") \ + $(int4 "${image_disk_size}") \ + $(string "${image_disk_mode}") \ + $(int1 "${image_disk_formatting}") \ + $(string "${image_disk_label}") \ + $(string "${read_password}") \ + $(string "${write_password}") \ + $(string "${multi_password}") + + # Tell user it was successful + echo "${image_disk_number} added to ${smtarg}" +} + +# ============================================================================= +# SMAPI Function: Image_Disk_Delete +# ============================================================================= +function Image_Disk_Delete +{ + # Define local variables + local i image_disk_number + + # Define info for parser + desc="Delete disk from active image" + required=(" -a | --addr address of disk") + optional=() + opts="a:" + optl="addr:" + usesparms="n" + + # Parse the command line + parseopts + + # Process options + for (( i = 0; i < ${#argv[@]}; i++ )) + do + case "${argv[i]}" in + -a | --addr) + i=$(( i + 1 )) + image_disk_number="${argv[i]}" + ;; + esac + done + + # Build and send the request + execute $(string "${image_disk_number}") + + # Tell user it was successful + echo "${image_disk_number} deleted from active ${smtarg}" +} + +# ============================================================================= +# SMAPI Function: Image_Disk_Delete_DM +# ============================================================================= +function Image_Disk_Delete_DM +{ + # Define local variables + local i image_disk_number data_security_erase + + # Define info for parser + desc="Delete disk from image" + required=(" -a | --addr address of disk") + optional=(" -e | --erase erase disks" \ + " : 0 = use installation default" \ + " : 1 = do not erase" \ + " : 2 = erase") + opts="a:e:" + optl="addr:,erase:" + usesparms="n" + + # Parse the command line + parseopts + + # Initialize optional fields + data_security_erase="0" + + # Process options + for (( i = 0; i < ${#argv[@]}; i++ )) + do + case "${argv[i]}" in + -a | --addr) + i=$(( i + 1 )) + image_disk_number="${argv[i]}" + ;; + + -e | --erase) + i=$(( i + 1 )) + data_security_erase="${argv[i]}" + ;; + esac + done + + # Build and send the request + execute $(string "${image_disk_number}") \ + $(int1 "${data_security_erase}") + + # Tell user it was successful + echo "${image_disk_number} deleted from ${smtarg}" +} + +# ============================================================================= +# SMAPI Function: Image_Disk_Query +# ============================================================================= +function Image_Disk_Query +{ + # Define local variables + local + + # Define info for parser + desc="Show all disks attached to target" + + # Build and send the request + execute_keywords + + # Show each entry until nothing left + while [ ${#resp} -gt 0 ] + do + getchars 4 vdasd_vdev + getchars 4 vdasd_rdev + get1 vdasd_access_type + getchars 4 vdasd_devtype + get8 vdasd_size + get1 vdasd_unit + getchars 6 vdasd_volid + getchars 1 vdasd_z + + # Convert vdasd_access_type + case "${vdasd_access_type}" in + 1) vdasd_access_type="${vdasd_access_type} (R/O)" ;; + 2) vdasd_access_type="${vdasd_access_type} (R/W)" ;; + *) vdasd_access_type="${vdasd_access_type} (??)" ;; + esac + + # Convert vdasd_unit_type + case "${vdasd_unit}" in + 1) vdasd_unit="${vdasd_unit} (Cylinders)" ;; + 2) vdasd_unit="${vdasd_unit} (Blocks)" ;; + *) vdasd_unit="${vdasd_unit} (??)" ;; + esac + + # Show it to the user + echo "Disk Info:" + echo " Virtual Address: ${vdasd_vdev}" + echo " Real Address: ${vdasd_rdev}" + echo " Access Type: ${vdasd_access_type}" + echo " Device Type: ${vdasd_devtype}" + echo " Size: ${vdasd_size}" + echo " Units: ${vdasd_unit}" + echo " Volume ID: ${vdasd_volid}" + echo + done +} + +# ============================================================================= +# SMAPI Function: Image_Disk_Share +# ============================================================================= +function Image_Disk_Share +{ + # Define local variables + local i image_disk_number target_image_name target_image_disk_number + local read_write_mode optional_password + + # Define info for parser + desc="Add link to active image" + required=(" -a | --addr device address" \ + " -o | --owner owner of target disk" \ + " -d | --disk address of target disk" \ + " -m | --mode link mode") + optional=(" -p | --pass link mode password") + opts="a:o:d:m:p:" + optl="addr:,owner:,disk:,mode:,pass:" + usesparms="n" + + # Parse the command line + parseopts + + # Initialize optional variables + optional_password="" + + # Process options + for (( i = 0; i < ${#argv[@]}; i++ )) + do + case "${argv[i]}" in + -a | --addr) + i=$(( i + 1 )) + image_disk_number="${argv[i]}" + ;; + + -o | --owner) + i=$(( i + 1 )) + target_image_name="${argv[i]}" + ;; + + -d | --disk) + i=$(( i + 1 )) + target_image_disk_number="${argv[i]}" + ;; + + -m | --mode) + i=$(( i + 1 )) + read_write_mode="${argv[i]}" + ;; + + -p | --pass) + i=$(( i + 1 )) + optional_password="${argv[i]}" + ;; + esac + done + + # Build and send the request + execute $(string "${image_disk_number}") \ + $(string "${target_image_name}") \ + $(string "${target_image_disk_number}") \ + $(string "${read_write_mode}") \ + $(string "${optional_password}") + + # Tell user it was successful + echo "Link to ${target_image_name} ${image_disk_number} added to active ${smtarg} as ${target_image_disk_number}" +} + +# ============================================================================= +# SMAPI Function: Image_Disk_Share_DM +# ============================================================================= +function Image_Disk_Share_DM +{ + # Define local variables + local i image_disk_number target_image_name target_image_disk_number + local read_write_mode optional_password + + # Define info for parser + desc="Add link to image" + required=(" -a | --addr device address" \ + " -o | --owner owner of target disk" \ + " -d | --disk address of target disk" \ + " -m | --mode link mode") + optional=(" -p | --pass link mode password") + opts="a:o:d:m:p:" + optl="addr:,owner:,disk:,mode:,pass:" + usesparms="n" + + # Parse the command line + parseopts + + # Initialize optional variables + optional_password="" + + # Process options + for (( i = 0; i < ${#argv[@]}; i++ )) + do + case "${argv[i]}" in + -a | --addr) + i=$(( i + 1 )) + image_disk_number="${argv[i]}" + ;; + + -o | --owner) + i=$(( i + 1 )) + target_image_name="${argv[i]}" + ;; + + -d | --disk) + i=$(( i + 1 )) + target_image_disk_number="${argv[i]}" + ;; + + -m | --mode) + i=$(( i + 1 )) + read_write_mode="${argv[i]}" + ;; + + -p | --pass) + i=$(( i + 1 )) + optional_password="${argv[i]}" + ;; + esac + done + + # Build and send the request + execute $(string "${image_disk_number}") \ + $(string "${target_image_name}") \ + $(string "${target_image_disk_number}") \ + $(string "${read_write_mode}") \ + $(string "${optional_password}") + + # Tell user it was successful + echo "Link to ${target_image_name} ${image_disk_number} added to ${smtarg} as ${target_image_disk_number}" +} + +# ============================================================================= +# SMAPI Function: Image_Disk_Unshare +# ============================================================================= +function Image_Disk_Unshare +{ + # Define local variables + local i image_disk_number + + # Define info for parser + desc="Remove link from active image" + required=(" -a | --addr device address") + optional=() + opts="a:" + optl="addr:" + usesparms="n" + + # Parse the command line + parseopts + + # Process options + for (( i = 0; i < ${#argv[@]}; i++ )) + do + case "${argv[i]}" in + -a | --addr) + i=$(( i + 1 )) + image_disk_number="${argv[i]}" + ;; + esac + done + + # Build and send the request + execute $(string "${image_disk_number}") + + # Tell user it was successful + echo "${image_disk_number} disk detached from ${smtarg}" +} + +# ============================================================================= +# SMAPI Function: Image_Disk_Unshare_DM +# ============================================================================= +function Image_Disk_Unshare_DM +{ + # Define local variables + local i image_disk_number target_image_name target_image_disk_number + + # Define info for parser + desc="Remove link from image" + required=(" -a | --addr device address" \ + " -o | --owner owner of target disk" \ + " -d | --disk address of target disk") + optional=() + opts="a:o:d:" + optl="addr:,owner:,disk:" + usesparms="n" + + # Parse the command line + parseopts + + # Process options + for (( i = 0; i < ${#argv[@]}; i++ )) + do + case "${argv[i]}" in + -a | --addr) + i=$(( i + 1 )) + image_disk_number="${argv[i]}" + ;; + + -o | --owner) + i=$(( i + 1 )) + target_image_name="${argv[i]}" + ;; + + -d | --disk) + i=$(( i + 1 )) + target_image_disk_number="${argv[i]}" + ;; + esac + done + + # Build and send the request + execute $(string "${image_disk_number}") \ + $(string "${target_image_name}") \ + $(string "${target_image_disk_number}") + + # Tell user it was successful + echo "${target_image_disk_number} removed from ${smtarg}" +} + +# ============================================================================= +# SMAPI Function: Image_IPL_Delete_DM +# ============================================================================= +function Image_IPL_Delete_DM +{ + # Define info for parser + desc="Delete IPL statement from image" + required=() + optional=() + opts="" + optl="" + usesparms="n" + + # Parse the command line + parseopts + + # Build and send the request + execute + + # Tell user it was successful + echo "IPL statement deleted from ${smtarg}" +} + +# ============================================================================= +# SMAPI Function: Image_IPL_Query_DM +# ============================================================================= +function Image_IPL_Query_DM +{ + # Define local variables + local saved_system load_parameter parameter_string + + # Define info for parser + desc="Query IPL statement in image" + required=() + optional=() + opts="" + optl="" + usesparms="n" + + # Parse the command line + parseopts + + # Build and send the request + execute + + # Retrieve return values + getstring saved_system + getstring load_parameter + getstring parameter_string + + # Show them to the user + echo "System or address: ${saved_system}" + echo "Load parameter: ${load_parameter}" + echo "IPL parameters: ${parameter_string}" +} + +# ============================================================================= +# SMAPI Function: Image_IPL_Set_DM +# ============================================================================= +function Image_IPL_Set_DM +{ + # Define local variables + local i saved_system load_parameter parameter_string + + # Define info for parser + desc="Lock image's directory or one of image's devices" + required=(" -n | --name saved segment name or device address") + optional=(" -l | --load load parameters" \ + " -p | --parm IPL parameters") + opts="n:l:p:" + optl="name:,load:,parm:" + usesparms="n" + + # Parse the command line + parseopts + + # Initialize optional fields + load_parameter="" + parameter_string="" + + # Process options + for (( i = 0; i < ${#argv[@]}; i++ )) + do + case "${argv[i]}" in + -n | --name) + i=$(( i + 1 )) + saved_system="${argv[i]}" + ;; + + -l | --load) + i=$(( i + 1 )) + load_parameter="${argv[i]}" + ;; + + -p | --parm) + i=$(( i + 1 )) + parameter_string="${argv[i]}" + ;; + esac + done + + # Build and send the request + execute $(string "${saved_system}") \ + $(string "${load_parameter}") \ + $(string "${parameter_string}") + + # Tell user it was successful + echo "IPL statement set in ${smtarg}" +} + +# ============================================================================= +# SMAPI Function: Image_Lock_DM +# ============================================================================= +function Image_Lock_DM +{ + # Define local variables + local i device_address + + # Define info for parser + desc="Lock image or one of its devices" + required=() + optional=(" -a | --addr device address") + opts="a:" + optl="addr:" + usesparms="n" + + # Parse the command line + parseopts + + # Initialize optional fields + device_address="" + + # Process options + for (( i = 0; i < ${#argv[@]}; i++ )) + do + case "${argv[i]}" in + -a | --addr) + i=$(( i + 1 )) + device_address="${argv[i]}" + ;; + esac + done + + # Build and send the request + execute $(string "${device_address}") + + # Tell user it was successful + if [ -z "${device_address}" ] + then + echo "${smtarg}'s locked" + else + echo "${smtarg}'s ${device_address} disk locked" + fi +} + +# ============================================================================= +# SMAPI Function: Image_Name_Query_DM +# ============================================================================= +function Image_Name_Query_DM +{ + # Define local variables + local + + # Define info for parser + desc="Retrieve list of defined virtual images" + required=() + optional=() + opts="" + optl="" + usesparms="n" + + # Parse the command line + parseopts + + # Build and send the request + execute + + # Retrieve and show the returned array + showstringarray +} + +# ============================================================================= +# SMAPI Function: Image_Password_Set_DM +# ============================================================================= +function Image_Password_Set_DM +{ + # Define local variables + local i image_password + + # Define info for parser + desc="Set password/passphrase for image" + required=(" -p | --pass image password/passphrase") + optional=() + opts="p:" + optl="pass:" + usesparms="n" + + # Parse the command line + parseopts + + # Process options + for (( i = 0; i < ${#argv[@]}; i++ )) + do + case "${argv[i]}" in + -p | --pass) + i=$(( i + 1 )) + image_password="${argv[i]}" + ;; + esac + done + + # Build and send the request + execute $(string "${image_password}") + + # Tell user it was successful + echo "Password/passphrase changed for ${smtarg}" +} + +# ============================================================================= +# SMAPI Function: Image_Query_Activate_Time +# ============================================================================= +function Image_Query_Activate_Time +{ + # Define local variables + local i date_format_indicator + local image_name activation_date activation_time + + # Define info for parser + desc="Query date/time when image was activated" + required=() + optional=(" -f | --format date format" \ + " : 1 = mm/dd/yy" \ + " : 2 = mm/dd/yyyy" \ + " : 3 = yy-mm-dd" \ + " : 4 = yyyy-mm-dd" \ + " : 5 = dd/mm/yy" \ + " : 6 = dd/mm/yyyy") + opts="f:" + optl="format:" + usesparms="n" + + # Parse the command line + parseopts + + # Initialize optional fields + date_format_indicator="1" + + # Process options + for (( i = 0; i < ${#argv[@]}; i++ )) + do + case "${argv[i]}" in + -f | --format) + i=$(( i + 1 )) + date_format_indicator="${argv[i]}" + ;; + esac + done + + # Build and send the request + execute $(int1 "${date_format_indicator}") + + # Retrieve returned values + getstring image_name + getstring activation_date + getstring activation_time + + # Show them to the user + echo "${image_name} was activated on ${activation_date} at ${activation_time}" +} + +# ============================================================================= +# SMAPI Function: Image_Query_DM +# ============================================================================= +function Image_Query_DM +{ + # Define local variables + local + + # Define info for parser + desc="Retrieve image's directory entry" + required=() + optional=() + opts="" + optl="" + usesparms="n" + + # Parse the command line + parseopts + + # Build and send the request + execute + + # Retrieve and show the returned array + showstringarray +} + +# ============================================================================= +# SMAPI Function: Image_Recycle +# ============================================================================= +function Image_Recycle +{ + # Define local variables + local recycled not_recycled image_name + local failing_array_length failing_structure_length + + # Define info for parser + desc="Activate image(s)" + required=() + optional=() + opts="" + optl="" + usesparms="n" + + # Parse the command line + parseopts + + # Build and send the request + execute_no_check + + # It was partially successful...show user what didn't recycle + if [ ${retc} -eq 200 -a ${reas} -eq 28 ] + then + # Retrieve the return values + get4 recycled + get4 not_recycled + + # Show them to the user + echo "Number of images recycled: ${recycled}" + echo "Number of images not recycled: ${not_recycled}" + + # Retrieve the length of the returned array + get4 failing_array_length + + # Retrieve and process array entries + while [ $failing_array_length -gt 0 ] + do + # Retrieve the entry length + get4 failing_structure_length + + # Protect against empty entries + if [ $failing_structure_length -gt 0 ] + then + # Retrieve the entry fields + getstring image_name + get4 retr + get4 reas + + # Tell the user why this one failed + echo "Activation of ${image_name} failed due to: " + showerror + echo + fi + + # Calculate remaining length (+4 for the "failing_structure_length" itself) + failing_array_length=$(( failing_array_length - 4 - failing_structure_length )) + done + + # Bail since we handled this error specifically + return + fi + + # Check for error + checkandfail + + # Tell user it was successful + echo "${smtarg} recycled" +} + +# ============================================================================= +# SMAPI Function: Image_Replace_DM +# ============================================================================= +function Image_Replace_DM +{ + # Define local variables + local image_record_array + + # Define info for parser + desc="Replace image's directory entry" + required=() + optional=() + opts="" + optl="" + usesparms="n" + + # Parse the command line + parseopts + + # Load array from stdin + loadarray image_record_array + + # Build and send the request + execute $(stringarray "${image_record_array[@]}") + + # Tell user it was successful + echo "${smtarg}'s directory entry replaced" +} + +# ============================================================================= +# SMAPI Function: Image_SCSI_Characteristics_Define_DM +# ============================================================================= +function Image_SCSI_Characteristics_Define_DM +{ + # Define local variables + local i boot_program BR_LBA LUN port_name SCP_data_type SCP_data + + # Define info for parser + desc="Define SCSI boot characteristics for image" + required=() + optional=(" -b | --boot boot program number or \"DELETE\"" \ + " -a | --addr logical block address of boot record or \"DELETE\"" \ + " -l | --lun logical unit number or \"DELETE\"" \ + " -p | --port port name or \"DELETE\"" \ + " -t | --type SCP data type, 0 - 3" \ + " -d | --data SCP data (format based on --type)") + opts="b:a:l:p:t:d:" + optl="boot:,addr:,lun:,port:,type:,data:" + usesparms="n" + + # Parse the command line + parseopts + + # Initialize optional fields + boot_program="" + BR_LBA="" + LUN="" + port_name="" + SCP_data_type="0" + SCP_data="" + + # Process options + for (( i = 0; i < ${#argv[@]}; i++ )) + do + case "${argv[i]}" in + -b | --boot) + i=$(( i + 1 )) + boot_program="${argv[i]}" + ;; + + -a | --addr) + i=$(( i + 1 )) + BR_LBA="${argv[i]}" + ;; + + -l | --lun) + i=$(( i + 1 )) + LUN="${argv[i]}" + ;; + + -p | --port) + i=$(( i + 1 )) + port_name="${argv[i]}" + ;; + + -t | --type) + i=$(( i + 1 )) + SCP_data_type="${argv[i]}" + ;; + + -d | --data) + i=$(( i + 1 )) + SCP_data="${argv[i]}" + ;; + esac + done + + # Convert SCP_data to EBCDIC if necessary + if [ "${SCP_data_type}" == "2" ] + then + SCP_data=$(echo -n "${SCP_data}" | dd conv=ebcdic) + fi + + # Build and send the request + execute $(string "${boot_program}") \ + $(string "${BR_LBA}") \ + $(string "${LUN}") \ + $(string "${port_name}") \ + $(int1 "${SCP_data_type}") \ + $(string "${SCP_data}") + + # Tell user it was successful + echo "${smtarg}'s SCSI characteristics updated" +} + +# ============================================================================= +# SMAPI Function: Image_SCSI_Characteristics_Query_DM +# ============================================================================= +function Image_SCSI_Characteristics_Query_DM +{ + # Define local variables + local boot_program BR_LBA LUN port_name SCP_data_type SCP_data + + # Define info for parser + desc="Query SCSI boot characteristics for image" + required=() + optional=() + opts="" + optl="" + usesparms="n" + + # Parse the command line + parseopts + + # Build and send the request + execute + + # Retrieve the length of the returned array + getstring boot_program + getstring BR_LBA + getstring LUN + getstring port_name + get1 SCP_data_type + getstring SCP_data + + # Convert SCP_data to ASCII if necessary + if [ "${SCP_data_type}" == "2" ] + then + SCP_data=$(echo -n "${SCP_data}" | dd conv=ascii) + fi + + # Show them to the user + echo "Boot program number: ${boot_program}" + echo "LBA of boot record: ${BR_LBA}" + echo "Logical unit number: ${LUN}" + echo "Port name: ${port_name}" + echo "SCP data type: ${SCP_data_type}" + echo "SCP data: ${SCP_data}" +} + +# ============================================================================= +# SMAPI Function: Image_Status_Query +# ============================================================================= +function Image_Status_Query +{ + # Define local variables + local + + # Define info for parser + desc="Determine active state of image(s)" + required=() + optional=() + opts="" + optl="" + usesparms="n" + + # Parse the command line + parseopts + + # Build and send the request + execute + + # Retrieve and show the returned array + showstringarray +} + +# ============================================================================= +# SMAPI Function: Image_Unlock_DM +# ============================================================================= +function Image_Unlock_DM +{ + # Define local variables + local i device_address + + # Define info for parser + desc="Unlock image or one of its devices" + required=() + optional=(" -a | --addr device address") + opts="a:" + optl="addr:" + usesparms="n" + + # Parse the command line + parseopts + + # Initialize optional fields + device_address="" + + # Process options + for (( i = 0; i < ${#argv[@]}; i++ )) + do + case "${argv[i]}" in + -a | --addr) + i=$(( i + 1 )) + device_address="${argv[i]}" + ;; + esac + done + + # Build and send the request + execute $(string "${device_address}") + + # Tell user it was successful + if [ -z "${device_address}" ] + then + echo "${smtarg}'s directory unlocked" + else + echo "${smtarg}'s ${device_address} disk unlocked" + fi +} + +# ============================================================================= +# SMAPI Function: Image_Volume_Add +# ============================================================================= +function Image_Volume_Add +{ + # Define local variables + local i + local image_device_number image_vol_id + local system_config_name system_config_type + local parm_disk_owner parm_disk_number parm_disk_password + local alt_system_config_name alt_system_config_type + local alt_parm_disk_owner alt_parm_disk_number alt_parm_disk_password + + # Define info for parser + desc="Add a DASD volume to system configuration file" + required=(" -a | --addr device address" \ + " -l | --label volume label") + optional=(" --confname system config name (default SYSTEM)" \ + " --conftype system config type (default CONFIG)" \ + " --parmowner parm disk owner (default MAINT)" \ + " --parmaddr parm disk address (default CF1)" \ + " --parmpass parm disk password (default \",\")" \ + " --altname alternate system config name (default SYSTEM)" \ + " --alttype alternate system config type (default CONFIG)" \ + " --altowner alternate parm disk owner (default MAINT)" \ + " --altaddr alternate parm disk address (default CF2)" \ + " --altpass alternate parm disk password (default \",\")") + opts="a:l:" + optl="addr:,label:" + optl="${optl},confname:,conftype:,parmowner:,parmaddr:,parmpass:" + optl="${optl},altname:,alttype:,altowner:,altaddr:,altpass:" + usesparms="n" + + # Parse the command line + parseopts + + # Initialize optional variables + system_config_name="" + system_config_type="" + parm_disk_owner="" + parm_disk_number="" + parm_disk_password="" + alt_system_config_name="" + alt_system_config_type="" + alt_parm_disk_owner="" + alt_parm_disk_number="" + alt_parm_disk_password="" + + # Process options + for (( i = 0; i < ${#argv[@]}; i++ )) + do + case "${argv[i]}" in + -a | --addr) + i=$(( i + 1 )) + image_device_number="${argv[i]}" + ;; + + -l | --label) + i=$(( i + 1 )) + image_vol_id="${argv[i]}" + ;; + + --confname) + i=$(( i + 1 )) + system_config_name="${argv[i]}" + ;; + + --conftype) + i=$(( i + 1 )) + system_config_type="${argv[i]}" + ;; + + --parmowner) + i=$(( i + 1 )) + parm_disk_owner="${argv[i]}" + ;; + + --parmaddr) + i=$(( i + 1 )) + parm_disk_number="${argv[i]}" + ;; + + --parmpass) + i=$(( i + 1 )) + parm_disk_password="${argv[i]}" + ;; + + --altname) + i=$(( i + 1 )) + alt_system_config_name="${argv[i]}" + ;; + + --alttype) + i=$(( i + 1 )) + alt_system_config_type="${argv[i]}" + ;; + + --altowner) + i=$(( i + 1 )) + alt_parm_disk_owner="${argv[i]}" + ;; + + --altaddr) + i=$(( i + 1 )) + alt_parm_disk_number="${argv[i]}" + ;; + + --altpass) + i=$(( i + 1 )) + alt_parm_disk_password="${argv[i]}" + ;; + esac + done + + # Build and send the request + execute $(string "${image_device_number}") \ + $(string "${image_vol_id}") \ + $(string "${system_config_name}") \ + $(string "${system_config_type}") \ + $(string "${parm_disk_owner}") \ + $(string "${parm_disk_number}") \ + $(string "${parm_disk_password}") \ + $(string "${alt_system_config_name}") \ + $(string "${alt_system_config_type}") \ + $(string "${alt_parm_disk_owner}") \ + $(string "${alt_parm_disk_number}") \ + $(string "${alt_parm_disk_password}") + + # Tell user it was successful + echo "${image_device_number} with label of ${image_vol_id} added to system configuration" +} + +# ============================================================================= +# SMAPI Function: Image_Volume_Delete +# ============================================================================= +function Image_Volume_Delete +{ + # Define local variables + local i + local image_device_number image_vol_id + local system_config_name system_config_type + local parm_disk_owner parm_disk_number parm_disk_password + local alt_system_config_name alt_system_config_type + local alt_parm_disk_owner alt_parm_disk_number alt_parm_disk_password + + # Define info for parser + desc="Delete a DASD volume from system configuration file" + required=(" -a | --addr device address" \ + " -l | --label volume label") + optional=(" --confname system config name (default SYSTEM)" \ + " --conftype system config type (default CONFIG)" \ + " --parmowner parm disk owner (default MAINT)" \ + " --parmaddr parm disk address (default CF1)" \ + " --parmpass parm disk password (default \",\")" \ + " --altname alternate system config name (default SYSTEM)" \ + " --alttype alternate system config type (default CONFIG)" \ + " --altowner alternate parm disk owner (default MAINT)" \ + " --altaddr alternate parm disk address (default CF2)" \ + " --altpass alternate parm disk password (default \",\")") + opts="a:l:" + optl="addr:,label:" + optl="${optl},confname:,conftype:,parmowner:,parmaddr:,parmpass:" + optl="${optl},altname:,alttype:,altowner:,altaddr:,altpass:" + usesparms="n" + + # Parse the command line + parseopts + + # Initialize optional variables + system_config_name="" + system_config_type="" + parm_disk_owner="" + parm_disk_number="" + parm_disk_password="" + alt_system_config_name="" + alt_system_config_type="" + alt_parm_disk_owner="" + alt_parm_disk_number="" + alt_parm_disk_password="" + + # Process options + for (( i = 0; i < ${#argv[@]}; i++ )) + do + case "${argv[i]}" in + -a | --addr) + i=$(( i + 1 )) + image_device_number="${argv[i]}" + ;; + + -l | --label) + i=$(( i + 1 )) + image_vol_id="${argv[i]}" + ;; + + --confname) + i=$(( i + 1 )) + system_config_name="${argv[i]}" + ;; + + --conftype) + i=$(( i + 1 )) + system_config_type="${argv[i]}" + ;; + + --parmowner) + i=$(( i + 1 )) + parm_disk_owner="${argv[i]}" + ;; + + --parmaddr) + i=$(( i + 1 )) + parm_disk_number="${argv[i]}" + ;; + + --parmpass) + i=$(( i + 1 )) + parm_disk_password="${argv[i]}" + ;; + + --altname) + i=$(( i + 1 )) + alt_system_config_name="${argv[i]}" + ;; + + --alttype) + i=$(( i + 1 )) + alt_system_config_type="${argv[i]}" + ;; + + --altowner) + i=$(( i + 1 )) + alt_parm_disk_owner="${argv[i]}" + ;; + + --altaddr) + i=$(( i + 1 )) + alt_parm_disk_number="${argv[i]}" + ;; + + --altpass) + i=$(( i + 1 )) + alt_parm_disk_password="${argv[i]}" + ;; + esac + done + + # Build and send the request + execute $(string "${image_device_number}") \ + $(string "${image_vol_id}") \ + $(string "${system_config_name}") \ + $(string "${system_config_type}") \ + $(string "${parm_disk_owner}") \ + $(string "${parm_disk_number}") \ + $(string "${parm_disk_password}") \ + $(string "${alt_system_config_name}") \ + $(string "${alt_system_config_type}") \ + $(string "${alt_parm_disk_owner}") \ + $(string "${alt_parm_disk_number}") \ + $(string "${alt_parm_disk_password}") + + # Tell user it was successful + echo "${image_device_number} with label of ${image_vol_id} deleted from system configuration" +} + +# ============================================================================= +# SMAPI Function: Image_Volume_Share +# ============================================================================= +function Image_Volume_Share +{ + # Define local variables + local + + # Define info for parser + desc="Share full-pack minidisk" + + # Build and send request + execute_keywords + + # Tell user it was successful + echo "Volume shared" +} + +# ============================================================================= +# SMAPI Function: Image_Volume_Space_Define_DM +# ============================================================================= +function Image_Volume_Space_Define_DM +{ + # Define local variables + local i + local function_type region_name image_vol_id + local start_cylinder size group_name device_type + + # Define info for parser + desc="Make DASD space available for use by images" + required=(" -f | --func function type" \ + " : 1 = define region" \ + " : 2 = define region, add to group" \ + " : 3 = define region as full volume" \ + " : 4 = define region as full volume, add to group" \ + " : 5 = add existing region to group" \ + " -r | --region region name") + optional=(" -v | --vol volume label (funcs: 1, 2, 3, 4)" \ + " -s | --start starting cylinder (funcs: 1, 2)" \ + " -c | --cyls number of cylinders (funcs: 1, 2)" \ + " -g | --group group name (funcs: 2, 4, 5)" \ + " -t | --type device type (funcs: 1, 2)" \ + " : 0 = Unspecified" \ + " : 1 = 3390" \ + " : 2 = 9336" \ + " : 3 = 3380" \ + " : 4 = FB-512") + opts="f:r:v:s:c:g:t:" + optl="func:,region:,vol:,start:,cyls:,group:,type:" + usesparms="n" + + # Parse the command line + parseopts + + # Initialize optional variables + image_vol_id="" + start_cylinder="-1" + size="-1" + group_name="" + device_type="0" + + # Process options + for (( i = 0; i < ${#argv[@]}; i++ )) + do + case "${argv[i]}" in + -f | --func) + i=$(( i + 1 )) + function_type="${argv[i]}" + ;; + + -r | --region) + i=$(( i + 1 )) + region_name="${argv[i]}" + ;; + + -v | --vol) + i=$(( i + 1 )) + image_vol_id="${argv[i]}" + ;; + + -s | --start) + i=$(( i + 1 )) + start_cylinder="${argv[i]}" + ;; + + -c | --cyls) + i=$(( i + 1 )) + size="${argv[i]}" + ;; + + -g | --group) + i=$(( i + 1 )) + group_name="${argv[i]}" + ;; + + -t | --type) + i=$(( i + 1 )) + device_type="${argv[i]}" + ;; + esac + done + + # Build and send the request + execute $(int1 "${function_type}") \ + $(string "${region_name}") \ + $(string "${image_vol_id}") \ + $(int4 "${start_cylinder}") \ + $(int4 "${size}") \ + $(string "${group_name}") \ + $(int1 "${device_type}") + + # Tell user it was successful + echo "Region ${region_name} made available for allocation" +} + +# ============================================================================= +# SMAPI Function: Image_Volume_Space_Define_Extended_DM +# ============================================================================= +function Image_Volume_Space_Define_Extended_DM +{ + # Define local variables + local + + # Define info for parser + desc="Define space on DASD volume" + required=() + optional=() + opts="" + optl="" + usesparms="o" + + # Parse the command line + parseopts + + # Build and send the request + execute $(int4 $(( ${#addparms} / 2 ))) \ + $addparms} + + # Tell user it was successful + echo "Space defined" +} + +# ============================================================================= +# SMAPI Function: Image_Volume_Space_Query_DM +# ============================================================================= +function Image_Volume_Space_Query_DM +{ + # Define local variables + local i + local query_type entry_type entry_names + + # Define info for parser + desc="Query space allocations for images" + required=(" -q | --query query type" \ + " : 1 = volume definition" \ + " : 2 = free space" \ + " : 3 = used space" \ + " -e | --entity entity type" \ + " : 1 = query specified volume" \ + " : 2 = query specified region" \ + " : 3 = query specified group") + optional=(" -n | --names entry names") + opts="q:e:n:" + optl="query:,entity:,names:" + usesparms="n" + + # Parse the command line + parseopts + + # Initialize optional variables + entry_names="" + + # Process options + for (( i = 0; i < ${#argv[@]}; i++ )) + do + case "${argv[i]}" in + -q | --query) + i=$(( i + 1 )) + query_type="${argv[i]}" + ;; + + -e | --entity) + i=$(( i + 1 )) + entity_type="${argv[i]}" + ;; + + -n | --names) + i=$(( i + 1 )) + entry_names="${argv[i]}" + ;; + esac + done + + # Build and send the request + execute $(int1 "${query_type}") \ + $(int1 "${entity_type}") \ + $(string "${entry_names}") + + # Retrieve and show the returned array + showstringarray +} + +# ============================================================================= +# SMAPI Function: Image_Volume_Space_Query_Extended_DM +# ============================================================================= +function Image_Volume_Space_Query_Extended_DM +{ + # Define local variables + local + + # Define info for parser + desc="Define space on DASD volume" + required=() + optional=() + opts="" + optl="" + usesparms="o" + + # Parse the command line + parseopts + + # Set defaults + query_type="" + entry_type="" + + # First option must be positional indicator + if [ "${argv[0]}" == "--" ] + then + # Process options + for (( i = 1; i < ${#argv[@]}; i++ )) + do + arg=$(tr <<<"${argv[i]}" "[:upper:]" "[:lower:]") + case "${arg%=*}" in + query_type) query_type="${arg#*=}" ;; + entry_type) entry_type="${arg#*=}" ;; + esac + done + fi + + # Complain if no additional parms were specified + if [ -z "${addparms}" ] + then + echo "Additional parameters not specified" + exit 1 + fi + + # Build and send the request + execute $(int4 $(( ${#addparms} / 2 ))) \ + $addparms} + + # Show each entry until nothing left + while [ ${#resp} -gt 0 ] + do + getasciiz record_structure + set -o noglob + set -- ${record_structure} + set +o noglob + + if [ "${query_type}" == "1" -a "${entry_type}" == "1" ] + then + echo " Volume ID: ${1}" + echo " Device Type: ${2}" + echo " Size: ${3}" + shift 3 + echo " Regions: ${*}" + elif [ "${query_type}" == "1" -a "${entry_type}" == "2" ] + then + echo " Region Name: ${1}" + echo " Volume ID: ${2}" + echo " Start Cylinder: ${3}" + echo " Device Type: ${4}" + echo " Size: ${5}" + shift 5 + echo " Groups: ${*}" + elif [ "${query_type}" == "1" -a "${entry_type}" == "3" ] + then + echo " Group Name: ${1}" + echo " Allocation Method: ${2}" + shift 2 + echo " Regions: ${*}" + elif [ "${query_type}" == "2" ] + then + echo " Volume ID: ${1}" + echo " Device Type: ${2}" + echo " Start Cylinder: ${3}" + echo " Size: ${4}" + echo " Group Name: ${5}" + echo " Region Name: ${6}" + elif [ "${query_type}" == "3" ] + then + echo " Volume ID: ${1}" + echo " Device Type: ${2}" + echo " Start Cylinder: ${3}" + echo " Size: ${4}" + echo " Owner: ${5}" + echo " VADDR: ${6}" + echo " Group Name: ${7}" + echo " Region Name: ${8}" + echo " SSI Node: ${9}" + shift 9 + echo " System Affinity: ${*}" + fi + echo + + done +} + +# ============================================================================= +# SMAPI Function: Image_Volume_Space_Remove_DM +# ============================================================================= +function Image_Volume_Space_Remove_DM +{ + # Define local variables + local i + local function_type region_name image_vol_id group_name + + # Define info for parser + desc="Remove DASD regions/groups from space pool" + required=(" -f | --func function type" \ + " : 1 = remove region" \ + " : 2 = remove region from group" \ + " : 3 = remove region from all groups" \ + " : 4 = remove all regions from volume" \ + " : 5 = remove all regions from volume and group" \ + " : 6 = remove all regions from volume and all groups" \ + " : 7 = remove entire group") + optional=(" -r | --region region name (funcs: 1, 2, 3)" \ + " -v | --vol volume label (funcs: 4, 5, 6)" \ + " -g | --group group name (funcs: 2, 5, 7)") + opts="f:r:v:g:" + optl="func:,region:,vol:,group:" + usesparms="n" + + # Parse the command line + parseopts + + # Initialize optional variables + region_name="" + image_vol_id="" + group_name="" + + # Process options + for (( i = 0; i < ${#argv[@]}; i++ )) + do + case "${argv[i]}" in + -f | --func) + i=$(( i + 1 )) + function_type="${argv[i]}" + ;; + + -r | --region) + i=$(( i + 1 )) + region_name="${argv[i]}" + ;; + + -v | --vol) + i=$(( i + 1 )) + image_vol_id="${argv[i]}" + ;; + + -g | --group) + i=$(( i + 1 )) + group_name="${argv[i]}" + ;; + esac + done + + # Build and send the request + execute $(int1 "${function_type}") \ + $(string "${region_name}") \ + $(string "${image_vol_id}") \ + $(string "${group_name}") + + # Tell user it was successful + echo "Space allocation pool updated" +} + +# ============================================================================= +# SMAPI Function: Metadata_Delete +# ============================================================================= +function Metadata_Delete +{ + # Define local variables + local i names + + # Define info for parser + desc="Delete metadata" + required=() + optional=() + opts="" + optl="" + usesparms="r" + + # Parse the command line + parseopts + + # First option must be positional indicator + if [ "${argv[0]}" != "--" ] + then + echo "Missing name list" + exit 1 + fi + + # Process names + names="" + for (( i = 1; i < ${#argv[@]}; i++ )) + do + names="${names} ${argv[i]}" + done + + # Build and send the request + execute $(asciiz "${names}") + + # Retrieve and show the returned array + echo "Metadata deleted" +} + +# ============================================================================= +# SMAPI Function: Metadata_Get +# ============================================================================= +function Metadata_Get +{ + # Define local variables + local i names + + # Define info for parser + desc="Get metadata" + required=() + optional=() + opts="" + optl="" + usesparms="r" + + # Parse the command line + parseopts + + # First option must be positional indicator + if [ "${argv[0]}" != "--" ] + then + echo "Missing name list" + exit 1 + fi + + # Process names + names="" + for (( i = 1; i < ${#argv[@]}; i++ )) + do + names="${names} ${argv[i]}" + done + + # Build and send the request + execute $(asciiz "${names}") + + # Retrieve the array length + get4 metadata_entry_array_length + + # Retrieve and process array entries + while [ ${metadata_entry_array_length} -gt 0 ] + do + # Retrieve the entry length + get4 metadata_entry_structure_length + + # Protect against empty entries + if [ ${metadata_entry_structure_length} -gt 0 ] + then + # Retrieve the entry fields + get4 metadata_entry_name_length + getchars ${metadata_entry_name_length} metadata_entry_name + get4 metadata_length + getchars ${metadata_length} metadata + + # Show it + echo "Metadata Entry:" + echo " Name: ${metadata_entry_name}" + echo " Data: ${metadata}" + fi + + # Calculate remaining length (+4 for the "CPU_info_structure_length" itself) + metadata_entry_array_length=$(( metadata_entry_array_length - 4 - metadata_entry_structure_length )) + done +} + +# ============================================================================= +# SMAPI Function: Metadata_Set +# ============================================================================= +function Metadata_Set +{ + # Define local variables + local i names + + # Define info for parser + desc="Get metadata" + required=() + optional=() + opts="" + optl="" + usesparms="r" + + # Parse the command line + parseopts + + # First option must be positional indicator + if [ "${argv[0]}" != "--" ] + then + echo "Missing name/value pairs" + exit 1 + fi + + # Ensure we have an even number of arguments + if [[ "${#argv[@]}" =~ .*[0248] ]] + then + echo "Incomplete name/value pairs" + exit 1 + fi + + # Process name/value pairs + names="" + for (( i = 1; i < ${#argv[@]}; i += 2 )) + do + pair="$(string ${argv[i]})$(string ${argv[i + 1]})" + pairs="${pairs}$(int4 ${#pair})${pair}" + done + + # Build and send the request + execute "$(int4 ${#pairs})${pairs}" + + # Tell user it was successful + echo "Metadata set" +} + +# ============================================================================= +# SMAPI Function: Name_List_Add +# ============================================================================= +function Name_List_Add +{ + # Define local variables + local i name + + # Define info for parser + desc="Add a userid or function name to a list" + required=(" -n | --name name to add") + optional=() + opts="n:" + optl="name:" + usesparms="n" + + # Parse the command line + parseopts + + # Process options + for (( i = 0; i < ${#argv[@]}; i++ )) + do + case "${argv[i]}" in + -n | --name) + i=$(( i + 1 )) + name="${argv[i]}" + ;; + esac + done + + # Build and send the request + execute $(string "${name}") + + # Tell user it was successful + echo "${name} added to the ${smtarg} list" +} + +# ============================================================================= +# SMAPI Function: Name_List_Destroy +# ============================================================================= +function Name_List_Destroy +{ + # Define local variables + local + + # Define info for parser + desc="Destroy an entire list" + required=() + optional=() + opts="" + optl="" + usesparms="n" + + # Parse the command line + parseopts + + # Build and send the request + execute + + # Tell user it was successful + echo "${smtarg} destroyed" +} + +# ============================================================================= +# SMAPI Function: Name_List_Query +# ============================================================================= +function Name_List_Query +{ + # Define local variables + local + + # Define info for parser + desc="Query names in a list or names of the available lists" + required=() + optional=() + opts="" + optl="" + usesparms="n" + + # Parse the command line + parseopts + + # Build and send the request + execute + + # Retrieve and show the returned array + showstringarray +} + +# ============================================================================= +# SMAPI Function: Name_List_Remove +# ============================================================================= +function Name_List_Remove +{ + # Define local variables + local i name + + # Define info for parser + desc="Remove a userid or function name from a list" + required=(" -n | --name name to remove") + optional=() + opts="n:" + optl="name:" + usesparms="n" + + # Parse the command line + parseopts + + # Process options + for (( i = 0; i < ${#argv[@]}; i++ )) + do + case "${argv[i]}" in + -n | --name) + i=$(( i + 1 )) + name="${argv[i]}" + ;; + esac + done + + # Build and send the request + execute $(string "${name}") + + # Tell user it was successful + echo "${name} removed from the ${smtarg} list" +} + +# ============================================================================= +# SMAPI Function: Page_or_Spool_Volume_Add +# ============================================================================= +function Page_or_Spool_Volume_Add +{ + # Define local variables + local + + # Define info for parser + desc="Add a page or spool volume to the system" + + # Build and send the request + execute_keywords + + # Tell user it was successful + echo "Volume added" +} + +# ============================================================================= +# SMAPI Function: Process_ABEND_Dump +# ============================================================================= +function Process_ABEND_Dump +{ + # Define local variables + local + + # Define info for parser + desc="Process and abend dump" + + # Build and send request + execute_keywords + + # Tell user it was successful + echo "Dump processed" +} + +# ============================================================================= +# SMAPI Function: Profile_Create_DM +# ============================================================================= +function Profile_Create_DM +{ + # Define local variables + local profile_record_array + + # Define info for parser + desc="Create a profile" + required=() + optional=() + opts="" + optl="" + usesparms="n" + + # Parse the command line + parseopts + + # Load array from stdin + loadarray profile_record_array + + # Build and send the request + execute $(stringarray "${profile_record_array[@]}") + + # Tell user it was successful + echo "${smtarg} profile created" +} + +# ============================================================================= +# SMAPI Function: Profile_Delete_DM +# ============================================================================= +function Profile_Delete_DM +{ + # Define local variables + local + + # Define info for parser + desc="Delete a profile" + required=() + optional=() + opts="" + optl="" + usesparms="n" + + # Parse the command line + parseopts + + # Build and send the request + execute + + # Tell user it was successful + echo "${smtarg} profile deleted" +} + +# ============================================================================= +# SMAPI Function: Profile_Lock_DM +# ============================================================================= +function Profile_Lock_DM +{ + # Define local variables + local + + # Define info for parser + desc="Lock a profile" + required=() + optional=() + opts="" + optl="" + usesparms="n" + + # Parse the command line + parseopts + + # Build and send the request + execute + + # Tell user it was successful + echo "${smtarg} profile locked" +} + +# ============================================================================= +# SMAPI Function: Profile_Query_DM +# ============================================================================= +function Profile_Query_DM +{ + # Define local variables + local + + # Define info for parser + desc="Retrieve a profile" + required=() + optional=() + opts="" + optl="" + usesparms="n" + + # Parse the command line + parseopts + + # Build and send the request + execute + + # Retrieve and show the returned array + showstringarray +} + +# ============================================================================= +# SMAPI Function: Profile_Replace_DM +# ============================================================================= +function Profile_Replace_DM +{ + # Define local variables + local profile_record_array + + # Define info for parser + desc="Replace a profile" + required=() + optional=() + opts="" + optl="" + usesparms="n" + + # Parse the command line + parseopts + + # Load array from stdin + loadarray profile_record_array + + # Build and send the request + execute $(stringarray "${profile_record_array[@]}") + + # Tell user it was successful + echo "${smtarg} profile replaced" +} + +# ============================================================================= +# SMAPI Function: Profile_Unlock_DM +# ============================================================================= +function Profile_Unlock_DM +{ + # Define local variables + local + + # Define info for parser + desc="Unlock a profile" + required=() + optional=() + opts="" + optl="" + usesparms="n" + + # Parse the command line + parseopts + + # Build and send the request + execute + + # Tell user it was successful + echo "${smtarg} profile unlocked" +} + +# ============================================================================= +# SMAPI Function: Prototype_Create_DM +# ============================================================================= +function Prototype_Create_DM +{ + # Define local variables + local prototype_record_array + + # Define info for parser + desc="Create prototype" + required=() + optional=() + opts="" + optl="" + usesparms="n" + + # Parse the command line + parseopts + + # Load array from stdin + loadarray prototype_record_array + + # Build and send the request + execute $(stringarray "${prototype_record_array[@]}") + + # Tell user it was successful + echo "${smtarg} prototype created" +} + +# ============================================================================= +# SMAPI Function: Prototype_Delete_DM +# ============================================================================= +function Prototype_Delete_DM +{ + # Define local variables + local + + # Define info for parser + desc="Delete prototype" + required=() + optional=() + opts="" + optl="" + usesparms="n" + + # Parse the command line + parseopts + + # Build and send the request + execute + + # Tell user it was successful + echo "${smtarg} prototype deleted" +} + +# ============================================================================= +# SMAPI Function: Prototype_Name_Query_DM +# ============================================================================= +function Prototype_Name_Query_DM +{ + # Define local variables + local + + # Define info for parser + desc="Retrieve list of defined prototypes" + required=() + optional=() + opts="" + optl="" + usesparms="n" + + # Parse the command line + parseopts + + # Build and send the request + execute + + # Retrieve and show the returned array + showstringarray +} + +# ============================================================================= +# SMAPI Function: Prototype_Query_DM +# ============================================================================= +function Prototype_Query_DM +{ + # Define local variables + local + + # Define info for parser + desc="Retrieve prototype" + required=() + optional=() + opts="" + optl="" + usesparms="n" + + # Parse the command line + parseopts + + # Build and send the request + execute + + # Retrieve and show the returned array + showstringarray +} + +# ============================================================================= +# SMAPI Function: Prototype_Replace_DM +# ============================================================================= +function Prototype_Replace_DM +{ + # Define local variables + local prototype_record_array + + # Define info for parser + desc="Replace prototype" + required=() + optional=() + opts="" + optl="" + usesparms="n" + + # Parse the command line + parseopts + + # Load array from stdin + loadarray prototype_record_array + + # Build and send the request + execute $(stringarray "${prototype_record_array[@]}") + + # Tell user it was successful + echo "${smtarg} prototype replaced" +} + +# ============================================================================= +# SMAPI Function: Query_ABEND_Dump +# ============================================================================= +function Query_ABEND_Dump +{ + # Define local variables + local + + # Define info for parser + desc="Display current dump information" + + # Build and send request + execute_keywords + + # Tell user it was successful + echo "Dump deletion requested" +} + +# ============================================================================= +# SMAPI Function: Query_All_DM +# ============================================================================= +function Query_All_DM +{ + # Define local variables + local i format + + # Define info for parser + desc="Create new virtual machine entry" + required=() + optional=() + opts="" + optl="" + usesparms="o" + + # Parse the command line + parseopts + + # Set to API default + format="yes" + + # First option must be positional indicator + if [ "${argv[0]}" == "--" ] + then + # Process options + for (( i = 1; i < ${#argv[@]}; i++ )) + do + if [[ "${argv[i]}" =~ [Ff][Oo][Rr][Mm][Aa][Tt]=[Nn].* ]] + then + format="no" + fi + done + fi + + # Complain if no additional parms were specified + if [ -z "${addparms}" ] + then + echo "Additional parameters not specified" + exit 1 + fi + + # Build and send the request + execute $(int4 $(( ${#addparms} / 2 ))) \ + ${addparms} + + # Retrieve the array length + get4 directory_entries_array_length + + # Retrieve and process array entries + while [ ${directory_entries_array_length} -gt 0 ] + do + # Retrieve the entry length + get4 directory_entry_structure_length + + # Protect against empty entries + if [ ${directory_entry_structure_length} -gt 0 ] + then + # Retrieve the entry fields + get4 directory_entry_type + getstring directory_entry_id + + # Convert directory_entry_type + case "${directory_entry_type}" in + 0) directory_entry_type="${directory_entry_type} (USER)" ;; + 1) directory_entry_type="${directory_entry_type} (PROFILE)" ;; + 2) directory_entry_type="${directory_entry_type} (USER)" ;; + 3) directory_entry_type="${directory_entry_type} (POOL)" ;; + 4) directory_entry_type="${directory_entry_type} (DIRECTORY)" ;; + 5) directory_entry_type="${directory_entry_type} (GLOBAL)" ;; + 6) directory_entry_type="${directory_entry_type} (IDENTITY)" ;; + 7) directory_entry_type="${directory_entry_type} (SUBCONFIG)" ;; + 8) directory_entry_type="${directory_entry_type} (OTHER)" ;; + *) directory_entry_type="${directory_entry_type} (?)" ;; + esac + + # Show it to the user + echo "Type: ${directory_entry_type}" + echo "ID: ${directory_entry_id}" + + if [ "${format}" = "yes" ] + then + get4 directory_entry_data_length + showasciizarray ${directory_entry_data_length} + else + showstringarray + fi + fi + + # Calculate remaining length (+4 for the "CPU_info_structure_length" itself) + directory_entries_array_length=$(( directory_entries_array_length - 4 - directory_entry_structure_length )) + done +} + +# ============================================================================= +# SMAPI Function: Query_API_Functional_Level +# ============================================================================= +function Query_API_Functional_Level +{ + # Define local variables + local + + # Define info for parser + desc="Query level of API" + required=() + optional=() + opts="" + optl="" + usesparms="n" + + # Parse the command line + parseopts + + # Build and send the request + execute_no_check + + # Show the level to the user + showerror + + # Bail if unsuccessful + if [ ${retc} -ne 0 ] + then + exit 1 + fi +} + +# ============================================================================= +# SMAPI Function: Query_Asynchronous_Operation_DM +# ============================================================================= +function Query_Asynchronous_Operation_DM +{ + # Define local variables + local i operation_id + + # Define info for parser + desc="Query status of an asynchronous operation" + required=(" -o | --opid operationl id") + optional=() + opts="o:" + optl="opid:" + usesparms="n" + + # Parse the command line + parseopts + + # Process options + for (( i = 0; i < ${#argv[@]}; i++ )) + do + case "${argv[i]}" in + -o | --opid) + i=$(( i + 1 )) + operation_id="${argv[i]}" + ;; + esac + done + + # Build and send the request + execute_no_check $(int4 "${operation_id}") + + # Show the user the status + showerror + + # Bail if unsuccessful + if [ ${retc} -ne 0 ] + then + exit 1 + fi +} + +# ============================================================================= +# SMAPI Function: Query_Directory_Manager_Level_DM +# ============================================================================= +function Query_Directory_Manager_Level_DM +{ + # Define local variables + local directory_manager_level + + # Define info for parser + desc="Query directory manager level" + required=() + optional=() + opts="" + optl="" + usesparms="n" + + # Parse the command line + parseopts + + # Build and send the request + execute + + # Retrieve return values + getstring directory_manager_level + + # Tell user it was successful + echo "${directory_manager_level}" +} + +# ============================================================================= +# SMAPI Function: Response_Recovery +# ============================================================================= +function Response_Recovery +{ + # Define local variables + local i request_id + + # Define info for parser + desc="Recover previosly failed response data" + required=(" -r | --reqid request id") + optional=() + opts="r:" + optl="reqid:" + usesparms="n" + + # Parse the command line + parseopts + + # Process options + for (( i = 0; i < ${#argv[@]}; i++ )) + do + case "${argv[i]}" in + -r | --reqid) + i=$(( i + 1 )) + request_id="${argv[i]}" + ;; + esac + done + + # Build and send the request + execute $(int4 "${request_id}") + + # Show the user the status + showerror + + # Bail if unsuccessful + if [ ${retc} -ne 0 ] + then + exit 1 + fi +} + +# ============================================================================= +# SMAPI Function: Shared_Memory_Access_Add_DM +# ============================================================================= +function Shared_Memory_Access_Add_DM +{ + # Define local variables + local i memory_segment_name + + # Define info for parser + desc="Add restricted access to a memory segment" + required=(" -n | --name name of memory segment") + optional=() + opts="n:" + optl="name:" + usesparms="n" + + # Parse the command line + parseopts + + # Process options + for (( i = 0; i < ${#argv[@]}; i++ )) + do + case "${argv[i]}" in + -n | --name) + i=$(( i + 1 )) + memory_segment_name="${argv[i]}" + ;; + esac + done + + # Build and send the request + execute $(string "${memory_segment_name}") + + # Tell user it was successful + echo "${smtarg} access added to memory segment ${memory_segment_name}" +} + +# ============================================================================= +# SMAPI Function: Shared_Memory_Access_Query_DM +# ============================================================================= +function Shared_Memory_Access_Query_DM +{ + # Define local variables + local i memory_segment_name + + # Define info for parser + desc="Query restricted access to a memory segment" + required=(" -n | --name name of memory segment") + optional=() + opts="n:" + optl="name:" + usesparms="n" + + # Parse the command line + parseopts + + # Process options + for (( i = 0; i < ${#argv[@]}; i++ )) + do + case "${argv[i]}" in + -n | --name) + i=$(( i + 1 )) + memory_segment_name="${argv[i]}" + ;; + esac + done + + # Build and send the request + execute $(string "${memory_segment_name}") + + # Retrieve and show the returned array + showstringarray +} + +# ============================================================================= +# SMAPI Function: Shared_Memory_Access_Remove_DM +# ============================================================================= +function Shared_Memory_Access_Remove_DM +{ + # Define local variables + local i memory_segment_name + + # Define info for parser + desc="Remove restricted access to a memory segment" + required=(" -n | --name name of memory segment") + optional=() + opts="n:" + optl="name:" + usesparms="n" + + # Parse the command line + parseopts + + # Process options + for (( i = 0; i < ${#argv[@]}; i++ )) + do + case "${argv[i]}" in + -n | --name) + i=$(( i + 1 )) + memory_segment_name="${argv[i]}" + ;; + esac + done + + # Build and send the request + execute $(string "${memory_segment_name}") + + # Tell user it was successful + echo "${smtarg} access removed to memory segment ${memory_segment_name}" +} + +# ============================================================================= +# SMAPI Function: Shared_Memory_Create +# ============================================================================= +function Shared_Memory_Create +{ + # Define local variables + local i memory_segment_name begin_page end_page + local page_access_descriptor memory_attributes + local memory_access_identifier + + # Define info for parser + desc="Create a shared memory segment" + required=(" -n | --name name of memory segment" \ + " -b | --begin beginning page (hex)" \ + " -e | --end ending page (hex)" \ + " -d | --desc page access descriptor" \ + " : 1 = SW" \ + " : 2 = EW" \ + " : 3 = SR" \ + " : 4 = ER" \ + " : 5 = SN" \ + " : 6 = EN" \ + " : 7 = SC") + optional=(" -a | --attr memory attributes" \ + " : 0 = Unspecified" \ + " : 1 = RSTD" \ + " : 2 = UNRSTD" \ + " -i | --id memory access ID") + opts="n:b:e:d:a:i:" + optl="name:,begin:,end:,desc:,attr:,id:" + usesparms="n" + + # Parse the command line + parseopts + + # Initialize optional variables + memory_attributes="0" + memory_access_identifier="" + + # Process options + for (( i = 0; i < ${#argv[@]}; i++ )) + do + case "${argv[i]}" in + -n | --name) + i=$(( i + 1 )) + memory_segment_name="${argv[i]}" + ;; + + -b | --begin) + i=$(( i + 1 )) + eval begin_page="\$((16#${argv[i]}))" + ;; + + -e | --end) + i=$(( i + 1 )) + eval end_page="\$((16#${argv[i]}))" + ;; + + -d | --desc) + i=$(( i + 1 )) + page_access_descriptor="${argv[i]}" + ;; + + -a | --attr) + i=$(( i + 1 )) + memory_attributes="${argv[i]}" + ;; + + -i | --id) + i=$(( i + 1 )) + memory_access_identifier="${argv[i]}" + ;; + esac + done + + # Build and send the request + execute $(string "${memory_segment_name}") \ + $(int8 "${begin_page}") \ + $(int8 "${end_page}") \ + $(int1 "${page_access_descriptor}") \ + $(int1 "${memory_attributes}") \ + $(string "${memory_access_identifier}") + + # Tell user it was successful + echo "${smtarg} memory saved to ${memory_segment_name}" +} + +# ============================================================================= +# SMAPI Function: Shared_Memory_Delete +# ============================================================================= +function Shared_Memory_Delete +{ + # Define local variables + local i memory_segment_name + + # Define info for parser + desc="Delete a shared memory segment" + required=(" -n | --name name of memory segment") + optional=() + opts="n:" + optl="name:" + usesparms="n" + + # Parse the command line + parseopts + + # Process options + for (( i = 0; i < ${#argv[@]}; i++ )) + do + case "${argv[i]}" in + -n | --name) + i=$(( i + 1 )) + memory_segment_name="${argv[i]}" + ;; + esac + done + + # Build and send the request + execute $(string "${memory_segment_name}") + + # Tell user it was successful + echo "Memory segment ${memory_segment_name} deleted" +} + +# ============================================================================= +# SMAPI Function: Shared_Memory_Query +# ============================================================================= +function Shared_Memory_Query +{ + # Define local variables + local i + local memory_segment_array_length memory_segment_structure_length + local memory_segment_name memory_segment_status + local page_range_array_length page_range_structure_length + local begin_page end_page page_access_descriptor + + # Define info for parser + desc="Query shared memory segment characteristics" + required=(" -n | --name name of memory segment") + optional=() + opts="n:" + optl="name:" + usesparms="n" + + # Parse the command line + parseopts + + # Process options + for (( i = 0; i < ${#argv[@]}; i++ )) + do + case "${argv[i]}" in + -n | --name) + i=$(( i + 1 )) + memory_segment_name="${argv[i]}" + ;; + esac + done + + # Build and send the request + execute $(string "${memory_segment_name}") + + # Retrieve the array length + get4 memory_segment_array_length + + # Retrieve and process array entries + while [ ${memory_segment_array_length} -gt 0 ] + do + # Retrieve the entry length + get4 memory_segment_structure_length + + # Protect against empty entries + if [ ${memory_segment_structure_length} -gt 0 ] + then + # Retrieve the entry fields + getstring memory_segment_name + get1 memory_segment_status + + # Convert memory_segment_status + case "${memory_segment_status}" in + 1) memory_segment_status="${memory_segment_status} (S)" ;; + 2) memory_segment_status="${memory_segment_status} (A)" ;; + 3) memory_segment_status="${memory_segment_status} (R)" ;; + *) memory_segment_status="${memory_segment_status} (?)" ;; + esac + + # Show it to the user + echo "Segment: ${memory_segment_name}" + echo "Status: ${memory_segment_status}" + + # Retrieve the array length + get4 page_range_array_length + + # Retrieve and process array entries + while [ ${page_range_array_length} -gt 0 ] + do + # Retrieve the entry length + get4 page_range_structure_length + + # Protect against empty entries + if [ ${page_range_structure_length} -gt 0 ] + then + # Retrieve the entry fields + get8 begin_page + get8 end_page + get1 page_access_descriptor + + # Convert page_access_descriptor + case "${page_access_descriptor}" in + 1) page_access_descriptor="${page_access_descriptor} (SW)" ;; + 2) page_access_descriptor="${page_access_descriptor} (EW)" ;; + 3) page_access_descriptor="${page_access_descriptor} (SR)" ;; + 4) page_access_descriptor="${page_access_descriptor} (ER)" ;; + 5) page_access_descriptor="${page_access_descriptor} (SN)" ;; + 6) page_access_descriptor="${page_access_descriptor} (EN)" ;; + 7) page_access_descriptor="${page_access_descriptor} (SC)" ;; + *) page_access_descriptor="${page_access_descriptor} (??)" ;; + esac + + # Show it to the user + printf "Range: %08x-%08x %s\n" "${begin_page}" "${end_page}" "${page_access_descriptor}" + fi + + # Calculate remaining length (+4 for the "CPU_info_structure_length" itself) + page_range_array_length=$(( page_range_array_length - 4 - page_range_structure_length )) + done + + echo + fi + + # Calculate remaining length (+4 for the "CPU_info_structure_length" itself) + memory_segment_array_length=$(( memory_segment_array_length - 4 - memory_segment_structure_length )) + done +} + +# ============================================================================= +# SMAPI Function: Shared_Memory_Replace +# ============================================================================= +function Shared_Memory_Replace +{ + # Define local variables + local i memory_segment_name memory_access_identifier + + # Define info for parser + desc="Replace a shared memory segment" + required=(" -n | --name name of memory segment") + optional=(" -i | --id memory access ID") + opts="n:i:" + optl="name:,id:" + usesparms="n" + + # Parse the command line + parseopts + + # Initialize optional variables + memory_access_identifier="" + + # Process options + for (( i = 0; i < ${#argv[@]}; i++ )) + do + case "${argv[i]}" in + -n | --name) + i=$(( i + 1 )) + memory_segment_name="${argv[i]}" + ;; + + -i | --id) + i=$(( i + 1 )) + memory_access_identifier="${argv[i]}" + ;; + esac + done + + # Build and send the request + execute $(string "${memory_segment_name}") \ + $(string "${memory_access_identifier}") + + # Tell user it was successful + echo "Memory segment ${memory_segment_name} replaced" +} + +# ============================================================================= +# SMAPI Function: SSI_Query +# ============================================================================= +function SSI_Query +{ + # Define local variables + local + + # Define info for parser + desc="Get SSI and system status" + + # Build and send the request + execute_keywords + + # Extract info + getasciiz ssi_name + getasciiz ssi_mode + getasciiz cross_system_timeouts + getasciiz ssi_pdr + + # Show it + echo "Name: ${ssi_name}" + echo "Mode: ${ssi_mode}" + echo "Cross System Timeouts: ${cross_system_timeouts}" + echo "PDR: ${ssi_pdr}" + + # Show each entry until nothing left + while [ ${#resp} -gt 0 ] + do + getasciiz info_structure + set -o noglob + set -- ${info_structure} + set +o noglob + + echo "Info:" + echo + + echo " Member Slot: ${1}" + echo " Member System ID: ${2}" + echo " Member State: ${3}" + echo " Member PDR Heartbeat: ${4}" + echo " Member Received Heartbeat: ${5}" + echo + done +} + +# ============================================================================= +# SMAPI Function: Static_Image_Changes_Activate_DM +# ============================================================================= +function Static_Image_Changes_Activate_DM +{ + # Define local variables + local + + # Define info for parser + desc="Enable automatic activattion of directory changes" + required=() + optional=() + opts="" + optl="" + usesparms="n" + + # Parse the command line + parseopts + + # Build and send the request + execute + + # Tell user it was successful + echo "Directory changes will be activated automatically" +} + +# ============================================================================= +# SMAPI Function: Static_Image_Changes_Deactivate_DM +# ============================================================================= +function Static_Image_Changes_Deactivate_DM +{ + # Define local variables + local + + # Define info for parser + desc="Disable automatic activation of directory changes" + required=() + optional=() + opts="" + optl="" + usesparms="n" + + # Parse the command line + parseopts + + # Build and send the request + execute + + # Tell user it was successful + echo "Directory changes will not be activated automatically" +} + +# ============================================================================= +# SMAPI Function: Static_Image_Changes_Immediate_DM +# ============================================================================= +function Static_Image_Changes_Immediate_DM +{ + # Define local variables + local + + # Define info for parser + desc="Force activattion pending changes to source directory" + required=() + optional=() + opts="" + optl="" + usesparms="n" + + # Parse the command line + parseopts + + # Build and send the request + execute + + # Tell user it was successful + echo "Changes to directory (if any) have been activated" +} + +# ============================================================================= +# SMAPI Function: System_Config_Syntax_Check +# ============================================================================= +function System_Config_Syntax_Check +{ + # Define local variables + local + + # Define info for parser + desc="Check the syntax of a system config file" + + # Build and send the request + execute_keywords + + # Tell user it was successful + echo "Syntax check successful" +} + +# ============================================================================= +# SMAPI Function: System_Disk_Accessibility +# ============================================================================= +function System_Disk_Accessibility +{ + # Define local variables + local + + # Define info for parser + desc="Verify accessibility of device" + + # Build and send the request + execute_keywords + + # Tell user it was successful + echo "Disk can be attached to system" +} + +# ============================================================================= +# SMAPI Function: System_Disk_Add +# ============================================================================= +function System_Disk_Add +{ + # Define local variables + local + + # Define info for parser + desc="Add disk to system" + + # Build and send the request + execute_keywords + + # Tell user it was successful + echo "Disk added to system" +} + +# ============================================================================= +# SMAPI Function: System_Disk_Query +# ============================================================================= +function System_Disk_Query +{ + # Define local variables + local + + # Define info for parser + desc="Query system disks" + + # Build and send the request + execute_keywords + + # Show each entry until nothing left + while [ ${#resp} -gt 0 ] + do + getasciiz disk_info_structure + set -- ${disk_info_structure} + + # Show it to the user + echo "Disk Info:" + echo " Device Number: ${1}" + echo " Device Type: ${2}" + echo " Device Status: ${3}" + echo " Device Volser: ${4}" + echo + done +} + +# ============================================================================= +# SMAPI Function: System_FCP_FreE_Query +# ============================================================================= +function System_FCP_Free_Query +{ + # Define local variables + local fcp_array + + # Define info for parser + desc="Query free FCP devices" + + # Build and send the request + execute_keywords + + # Show each entry until nothing left + while [ ${#resp} -gt 0 ] + do + getasciiz fcp_structure + OIFS="${IFS}" + IFS=';' + set -- ${fcp_structure} + IFS="${OIFS}" + + # Show it to the user + echo "FCP Info:" + echo " Device Number: ${1}" + echo " WWPN: ${2}" + echo " LUN: ${3}" + echo " UUID: ${4}" + echo " Vendor Name: ${5}" + echo " Product Number: ${6}" + echo " Model Number: ${7}" + echo " Serial Number: ${8}" + echo " Device Code: ${9}" + shift 9 + echo " Block Size: ${1}" + echo " Disk Blocks: ${2}" + echo " LUN Size: ${3}" + echo + done +} + +# ============================================================================= +# SMAPI Function: System_Performance_Threshold_Disable +# ============================================================================= +function System_Performance_Threshold_Disable +{ + # Define local variables + local i event_type + + # Define info for parser + desc="Disable async threshold events" + required=() + optional=() + opts="" + optl="" + usesparms="r" + + # Parse the command line + parseopts + + # First option must be positional indicator + if [ "${argv[0]}" != "--" ] + then + echo "Missing event type" + exit 1 + fi + + # Reconstruct event type + event_type="" + for (( i = 1; i < ${#argv[@]}; i++ )) + do + event_type="${event_type} ${argv[i]}" + done + + # Build and send the request + execute $(asciiz "${event_type}") + + # Tell user it was successful + echo "Performance threshold events disabled" +} + +# ============================================================================= +# SMAPI Function: System_Performance_Threshold_Enable +# ============================================================================= +function System_Performance_Threshold_Enable +{ + # Define local variables + local i event_type + + # Define info for parser + desc="Enable async threshold events" + required=() + optional=() + opts="" + optl="" + usesparms="r" + + # Parse the command line + parseopts + + # First option must be positional indicator + if [ "${argv[0]}" != "--" ] + then + echo "Missing event type" + exit 1 + fi + + # Reconstruct event type + event_type="" + for (( i = 1; i < ${#argv[@]}; i++ )) + do + event_type="${event_type} ${argv[i]}" + done + + # Build and send the request + execute $(asciiz "${event_type}") + + # Tell user it was successful + echo "Performance threshold events enabled" +} + +# ============================================================================= +# SMAPI Function: System_SCSI_Disk_Add +# ============================================================================= +function System_SCSI_Disk_Add +{ + # Define local variables + local + + # Define info for parser + desc="Add SCSI disk to system" + + # Build and send the request + execute_keywords + + # Tell user it was successful + echo "SCSI disk added to system" +} + +# ============================================================================= +# SMAPI Function: System_SCSI_Disk_Delete +# ============================================================================= +function System_SCSI_Disk_Delete +{ + # Define local variables + local + + # Define info for parser + desc="Delete SCSI disk from system" + + # Build and send the request + execute_keywords + + # Tell user it was successful + echo "SCSI disk deleted from system" +} + +# ============================================================================= +# SMAPI Function: System_SCSI_Disk_Query +# ============================================================================= +function System_SCSI_Disk_Query +{ + # Define local variables + local fcp_array + + # Define info for parser + desc="Query SCSI system disks" + + # Build and send the request + execute_keywords + + # Show each entry until nothing left + while [ ${#resp} -gt 0 ] + do + getasciiz scsi_info_structure + set -- ${scsi_info_structure} + + # Show it to the user + echo "SCSI Info:" + echo " Device Number: ${1}" + echo " Device Type: ${2}" + echo " Device Attr: ${3}" + echo " Device Size: ${4}" + echo " FCP Devices:" + + fcp_array = "${5}" + while [ ${#fcp_array} -gt 0 ] + do + echo " FCP Device number: ${fcp_array:0:4}" + echo " WWPN: ${fcp_array:4:16}" + echo " LUN: ${fcp_array:20:16}" + + fcp_array="${fcp_array:36}" + done + + echo + done +} + +# ============================================================================= +# SMAPI Function: System_WWPN_Query +# ============================================================================= +function System_WWPN_Query +{ + # Define local variables + local fcp_array + + # Define info for parser + desc="Query FCP devices" + + # Build and send the request + execute_keywords + + # Show each entry until nothing left + while [ ${#resp} -gt 0 ] + do + getasciiz wwpn_structure + set -- ${wwpn_structure} + + # Show it to the user + echo "WWPN Info:" + echo " Device Number: ${1}" + echo " NPIV Port Number: ${2}" + echo " CHPID: ${3}" + echo " Physical WWPN: ${4}" + + case "${5}" in + 1) echo " ${5} (Active)" ;; + 2) echo " ${5} (Free)" ;; + 3) echo " ${5} (Offline)" ;; + *) echo " ${5} (?)" ;; + esac + + echo + done +} + +# ============================================================================= +# SMAPI Function: Virtual_Channel_Connection_Create +# ============================================================================= +function Virtual_Channel_Connection_Create +{ + # Define local variables + local i image_device_number coupled_image_name coupled_image_device_number + + # Define info for parser + desc="Create virtual network connection (CTCA) between active images" + required=(" -a | --addr address of device in target" \ + " -n | --name name of partner image" \ + " -d | --dev address of device in partner") + optional=() + opts="a:n:d:" + optl="addr:,name:,dev:" + usesparms="n" + + # Parse the command line + parseopts + + # Process options + for (( i = 0; i < ${#argv[@]}; i++ )) + do + case "${argv[i]}" in + -a | --addr) + i=$(( i + 1 )) + image_device_number="${argv[i]}" + ;; + + -n | --name) + i=$(( i + 1 )) + coupled_image_name="${argv[i]}" + ;; + + -d | --dev) + i=$(( i + 1 )) + coupled_image_device_number="${argv[i]}" + ;; + esac + done + + # Build and send the request + execute $(string "${image_device_number}") \ + $(string "${coupled_image_name}") \ + $(string "${coupled_image_device_number}") + + # Tell user it was successful + echo "${image_device_number} connected to active ${coupled_image_name}'s ${coupled_image_device_number} device" +} + +# ============================================================================= +# SMAPI Function: Virtual_Channel_Connection_Create_DM +# ============================================================================= +function Virtual_Channel_Connection_Create_DM +{ + # Define local variables + local i image_device_number coupled_image_name + + # Define info for parser + desc="Create virtual network connection (CTCA) between images" + required=(" -a | --addr address of device" \ + " -n | --name name of partner image") + optional=() + opts="a:n:" + optl="addr:,name:" + usesparms="n" + + # Parse the command line + parseopts + + # Process options + for (( i = 0; i < ${#argv[@]}; i++ )) + do + case "${argv[i]}" in + -a | --addr) + i=$(( i + 1 )) + image_device_number="${argv[i]}" + ;; + + -n | --name) + i=$(( i + 1 )) + coupled_image_name="${argv[i]}" + ;; + esac + done + + # Build and send the request + execute $(string "${image_device_number}") \ + $(string "${coupled_image_name}") + + # Tell user it was successful + echo "${image_device_number} created and connected to ${coupled_image_name}" +} + +# ============================================================================= +# SMAPI Function: Virtual_Channel_Connection_Delete +# ============================================================================= +function Virtual_Channel_Connection_Delete +{ + # Define local variables + local i image_device_number + + # Define info for parser + desc="Delete virtual network connection (CTCA) from active image" + required=(" -a | --addr address of device") + optional=() + opts="a:" + optl="addr:" + usesparms="n" + + # Parse the command line + parseopts + + # Process options + for (( i = 0; i < ${#argv[@]}; i++ )) + do + case "${argv[i]}" in + -a | --addr) + i=$(( i + 1 )) + image_device_number="${argv[i]}" + ;; + esac + done + + # Build and send the request + execute $(string "${image_device_number}") + + # Tell user it was successful + echo "${image_device_number} CTCA deleted from active ${smtarg}" +} + +# ============================================================================= +# SMAPI Function: Virtual_Channel_Connection_Delete_DM +# ============================================================================= +function Virtual_Channel_Connection_Delete_DM +{ + # Define local variables + local i image_device_number + + # Define info for parser + desc="Delete virtual network connection (CTCA) from image directory" + required=(" -a | --addr address of device") + optional=() + opts="a:" + optl="addr:" + usesparms="n" + + # Parse the command line + parseopts + + # Process options + for (( i = 0; i < ${#argv[@]}; i++ )) + do + case "${argv[i]}" in + -a | --addr) + i=$(( i + 1 )) + image_device_number="${argv[i]}" + ;; + esac + done + + # Build and send the request + execute $(string "${image_device_number}") + + # Tell user it was successful + echo "${image_device_number} CTCA deleted from ${smtarg}" +} + +# ============================================================================= +# SMAPI Function: Virtual_Network_Adapter_Connect_LAN +# ============================================================================= +function Virtual_Network_Adapter_Connect_LAN +{ + # Define local variables + local i image_device_number lan_name lan_owner + + # Define info for parser + desc="Connect an active image's network adapter to LAN" + required=(" -a | --addr address of device" \ + " -n | --name LAN name" \ + " -o | --owner LAN owner") + optional=() + opts="a:n:o:" + optl="addr:,name:,owner:" + usesparms="n" + + # Parse the command line + parseopts + + # Process options + for (( i = 0; i < ${#argv[@]}; i++ )) + do + case "${argv[i]}" in + -a | --addr) + i=$(( i + 1 )) + image_device_number="${argv[i]}" + ;; + + -n | --name) + i=$(( i + 1 )) + lan_name="${argv[i]}" + ;; + + -o | --owner) + i=$(( i + 1 )) + lan_owner="${argv[i]}" + ;; + esac + done + + # Build and send the request + execute $(string "${image_device_number}") \ + $(string "${lan_name}") \ + $(string "${lan_owner}") + + # Tell user it was successful + echo "${image_device_number} connected to active ${lan_owner} ${lan_name}" +} + +# ============================================================================= +# SMAPI Function: Virtual_Network_Adapter_Connect_LAN_DM +# ============================================================================= +function Virtual_Network_Adapter_Connect_LAN_DM +{ + # Define local variables + local i image_device_number lan_name lan_owner + + # Define info for parser + desc="Connect an active image's network adapter to LAN" + required=(" -a | --addr address of device" \ + " -n | --name LAN name" \ + " -o | --owner LAN owner") + optional=() + opts="a:n:o:" + optl="addr:,name:,owner:" + usesparms="n" + + # Parse the command line + parseopts + + # Process options + for (( i = 0; i < ${#argv[@]}; i++ )) + do + case "${argv[i]}" in + -a | --addr) + i=$(( i + 1 )) + image_device_number="${argv[i]}" + ;; + + -n | --name) + i=$(( i + 1 )) + lan_name="${argv[i]}" + ;; + + -o | --owner) + i=$(( i + 1 )) + lan_owner="${argv[i]}" + ;; + esac + done + + # Build and send the request + execute $(string "${image_device_number}") \ + $(string "${lan_name}") \ + $(string "${lan_owner}") + + # Tell user it was successful + echo "${image_device_number} connected to ${lan_owner} ${lan_name}" +} + +# ============================================================================= +# SMAPI Function: Virtual_Network_Adapter_Connect_Vswitch +# ============================================================================= +function Virtual_Network_Adapter_Connect_Vswitch +{ + # Define local variables + local i image_device_number vswitch_name + + # Define info for parser + desc="Connect an active image's network adapter to a virtual switch" + required=(" -a | --addr address of device" \ + " -n | --name Vswitch name") + optional=() + opts="a:n:" + optl="addr:,name:" + usesparms="n" + + # Parse the command line + parseopts + + # Process options + for (( i = 0; i < ${#argv[@]}; i++ )) + do + case "${argv[i]}" in + -a | --addr) + i=$(( i + 1 )) + image_device_number="${argv[i]}" + ;; + + -n | --name) + i=$(( i + 1 )) + vswitch_name="${argv[i]}" + ;; + esac + done + + # Build and send the request + execute $(string "${image_device_number}") \ + $(string "${vswitch_name}") + + # Tell user it was successful + echo "${image_device_number} connected to active ${vswitch_name}" +} + +# ============================================================================= +# SMAPI Function: Virtual_Network_Adapter_Connect_Vswitch_DM +# ============================================================================= +function Virtual_Network_Adapter_Connect_Vswitch_DM +{ + # Define local variables + local i image_device_number vswitch_name + + # Define info for parser + desc="Connect an active image's network adapter to a virtual switch" + required=(" -a | --addr address of device" \ + " -n | --name Vswitch name") + optional=() + opts="a:n:" + optl="addr:,name:" + usesparms="n" + + # Parse the command line + parseopts + + # Process options + for (( i = 0; i < ${#argv[@]}; i++ )) + do + case "${argv[i]}" in + -a | --addr) + i=$(( i + 1 )) + image_device_number="${argv[i]}" + ;; + + -n | --name) + i=$(( i + 1 )) + vswitch_name="${argv[i]}" + ;; + esac + done + + # Build and send the request + execute $(string "${image_device_number}") \ + $(string "${vswitch_name}") + + # Tell user it was successful + echo "${image_device_number} connected to ${vswitch_name}" +} + +# ============================================================================= +# SMAPI Function: Virtual_Network_Adapter_Connect_Vswitch__Extended +# ============================================================================= +function Virtual_Network_Adapter_Connect_Vswitch_Extended +{ + # Define local variables + local + + # Define info for parser + desc="Connect active adapter to existing switch" + + # Build and send the request + execute_keywords + + # Tell user it was successful + echo "Adapter connected to active ${smtarg}" +} + +# ============================================================================= +# SMAPI Function: Virtual_Network_Adapter_Create +# ============================================================================= +function Virtual_Network_Adapter_Create +{ + # Define local variables + local i image_device_number adapter_type network_adapter_devices + local channel_path_id + + # Define info for parser + desc="Add a network adapter to an active image" + required=(" -a | --addr address of device" \ + " -t | --type adapter type" \ + " : 1 = hipersocket NIC" \ + " : 2 = QDIO NIC" \ + " -d | --devices number of devices") + optional=(" -p | --path channel path ID") + opts="a:t:d:p:" + optl="addr:,type:,devices:,path:" + usesparms="n" + + # Parse the command line + parseopts + + # Initialize optional variables + channel_path_id="" + + # Process options + for (( i = 0; i < ${#argv[@]}; i++ )) + do + case "${argv[i]}" in + -a | --addr) + i=$(( i + 1 )) + image_device_number="${argv[i]}" + ;; + + -t | --type) + i=$(( i + 1 )) + adapter_type="${argv[i]}" + ;; + + -d | --devices) + i=$(( i + 1 )) + network_adapter_devices="${argv[i]}" + ;; + + -p | --path) + i=$(( i + 1 )) + channel_path_id="${argv[i]}" + ;; + esac + done + + # Build and send the request + execute $(string "${image_device_number}") \ + $(int1 "${adapter_type}") \ + $(int4 "${network_adapter_devices}") \ + $(string "${channel_path_id}") + + # Tell user it was successful + echo "${image_device_number} added to active ${smtarg}" +} + +# ============================================================================= +# SMAPI Function: Virtual_Network_Adapter_Create_DM +# ============================================================================= +function Virtual_Network_Adapter_Create_DM +{ + # Define local variables + local i image_device_number adapter_type network_adapter_devices + local channel_path_id mac_id + + # Define info for parser + desc="Add a network adapter to an image" + required=(" -a | --addr address of device" \ + " -t | --type adapter type" \ + " : 1 = hipersocket NIC" \ + " : 2 = QDIO NIC" \ + " -d | --devices number of devices") + optional=(" -p | --path channel path ID" \ + " -m | --mac mac ID") + opts="a:t:d:p:m:" + optl="addr:,type:,devices:,path:,mac:" + usesparms="n" + + # Parse the command line + parseopts + + # Initialize optional variables + channel_path_id="" + mac_id="" + + # Process options + for (( i = 0; i < ${#argv[@]}; i++ )) + do + case "${argv[i]}" in + -a | --addr) + i=$(( i + 1 )) + image_device_number="${argv[i]}" + ;; + + -t | --type) + i=$(( i + 1 )) + adapter_type="${argv[i]}" + ;; + + -d | --devices) + i=$(( i + 1 )) + network_adapter_devices="${argv[i]}" + ;; + + -p | --path) + i=$(( i + 1 )) + channel_path_id="${argv[i]}" + ;; + + -m | --mac) + i=$(( i + 1 )) + mac_id="${argv[i]}" + ;; + esac + done + + # Build and send the request + execute $(string "${image_device_number}") \ + $(int1 "${adapter_type}") \ + $(int4 "${network_adapter_devices}") \ + $(string "${channel_path_id}") \ + $(string "${mac_id}") + + # Tell user it was successful + echo "${image_device_number} added to ${smtarg}" +} + +# ============================================================================= +# SMAPI Function: Virtual_Network_Adapter_Create_Extended +# ============================================================================= +function Virtual_Network_Adapter_Create_Extended +{ + # Define local variables + local + + # Define info for parser + desc="Add a network adapter to an active image" + + # Build and send the request + execute_keywords + + # Tell user it was successful + echo "Adapter added to active ${smtarg}" +} + +# ============================================================================= +# SMAPI Function: Virtual_Network_Adapter_Create_Extended_DM +# ============================================================================= +function Virtual_Network_Adapter_Create_Extended_DM +{ + # Define local variables + local + + # Define info for parser + desc="Add a network adapter to an image" + required=() + optional=() + opts="" + optl="" + usesparms="o" + + # Parse the command line + parseopts + + # Build and send the request + execute $(int4 $(( ${#addparms} / 2 ))) \ + $addparms} + + # Tell user it was successful + echo "Adapter added to ${smtarg}" +} + +# ============================================================================= +# SMAPI Function: Virtual_Network_Adapter_Delete +# ============================================================================= +function Virtual_Network_Adapter_Delete +{ + # Define local variables + local i image_device_number + + # Define info for parser + desc="Delete a network adapter from an active image" + required=(" -a | --addr address of device") + optional=() + opts="a:" + optl="addr:" + usesparms="n" + + # Parse the command line + parseopts + + # Process options + for (( i = 0; i < ${#argv[@]}; i++ )) + do + case "${argv[i]}" in + -a | --addr) + i=$(( i + 1 )) + image_device_number="${argv[i]}" + ;; + esac + done + + # Build and send the request + execute $(string "${image_device_number}") + + # Tell user it was successful + echo "${image_device_number} deleted from active ${smtarg}" +} + +# ============================================================================= +# SMAPI Function: Virtual_Network_Adapter_Delete_DM +# ============================================================================= +function Virtual_Network_Adapter_Delete_DM +{ + # Define local variables + local i image_device_number + + # Define info for parser + desc="Delete a network adapter from an image" + required=(" -a | --addr address of device") + optional=() + opts="a:" + optl="addr:" + usesparms="n" + + # Parse the command line + parseopts + + # Process options + for (( i = 0; i < ${#argv[@]}; i++ )) + do + case "${argv[i]}" in + -a | --addr) + i=$(( i + 1 )) + image_device_number="${argv[i]}" + ;; + esac + done + + # Build and send the request + execute $(string "${image_device_number}") + + # Tell user it was successful + echo "${image_device_number} deleted from ${smtarg}" +} + +# ============================================================================= +# SMAPI Function: Virtual_Network_Adapter_Disconnect +# ============================================================================= +function Virtual_Network_Adapter_Disconnect +{ + # Define local variables + local i image_device_number + + # Define info for parser + desc="Disconnect network adapter in an active image" + required=(" -a | --addr address of device") + optional=() + opts="a:" + optl="addr:" + usesparms="n" + + # Parse the command line + parseopts + + # Process options + for (( i = 0; i < ${#argv[@]}; i++ )) + do + case "${argv[i]}" in + -a | --addr) + i=$(( i + 1 )) + image_device_number="${argv[i]}" + ;; + esac + done + + # Build and send the request + execute $(string "${image_device_number}") + + # Tell user it was successful + echo "${image_device_number} disconnected in ${smtarg}" +} + +# ============================================================================= +# SMAPI Function: Virtual_Network_Adapter_Disconnect_DM +# ============================================================================= +function Virtual_Network_Adapter_Disconnect_DM +{ + # Define local variables + local i image_device_number + + # Define info for parser + desc="Disconnect a network adapter in an image" + required=(" -a | --addr address of device") + optional=() + opts="a:" + optl="addr:" + usesparms="n" + + # Parse the command line + parseopts + + # Process options + for (( i = 0; i < ${#argv[@]}; i++ )) + do + case "${argv[i]}" in + -a | --addr) + i=$(( i + 1 )) + image_device_number="${argv[i]}" + ;; + esac + done + + # Build and send the request + execute $(string "${image_device_number}") + + # Tell user it was successful + echo "${image_device_number} disconnected in ${smtarg}" +} + +# ============================================================================= +# SMAPI Function: Virtual_Network_Adapter_Query +# ============================================================================= +function Virtual_Network_Adapter_Query +{ + # Define local variables + local i image_device_number + local adapter_array_length adapter_structure_length + local image_device_number adapter_type network_adapter_devices + local adapter_status lan_owner lan_name + + # Define info for parser + desc="Query network adapter(s) in an active image" + required=(" -a | --addr address of device") + optional=() + opts="a:" + optl="addr:" + usesparms="n" + + # Parse the command line + parseopts + + # Process options + for (( i = 0; i < ${#argv[@]}; i++ )) + do + case "${argv[i]}" in + -a | --addr) + i=$(( i + 1 )) + image_device_number="${argv[i]}" + ;; + esac + done + + # Build and send the request + execute $(string "${image_device_number}") + + # Retrieve the length of the returned array + get4 adapter_array_length + + # Retrieve and process array entries + while [ $adapter_array_length -gt 0 ] + do + # Retrieve the entry length + get4 adapter_structure_length + + # Protect against empty entries + if [ $adapter_structure_length -gt 0 ] + then + # Retrieve entry fields + getstring image_device_number + get1 adapter_type + get4 network_adapter_devices + get1 adapter_status + getstring lan_owner + getstring lan_name + + # Convert adapter_type + case "${adapter_type}" in + 1) adapter_type="${adapter_type} (Hipersocket)" ;; + 2) adapter_type="${adapter_type} (QDIO)" ;; + *) adapter_type="${adapter_type} (??)" ;; + esac + + # Convert adapter_status + case "${adapter_status}" in + 0) adapter_status="${adapter_status} (not coupled)" ;; + 1) adapter_status="${adapter_status} (coupled, not active)" ;; + 2) adapter_status="${adapter_status} (coupled, active)" ;; + *) adapter_status="${adapter_status} (??)" ;; + esac + + # Show it to the user + echo "Adapter:" + echo " Address: ${image_device_number}" + echo " Device count: ${network_adapter_devices}" + echo " Adapter type: ${adapter_type}" + echo " Adapter status: ${adapter_status}" + echo " Lan owner: ${lan_owner}" + echo " Lan name: ${lan_name}" + echo + fi + + # Calculate remaining length (+4 for the "adapter_structure_length" itself) + adapter_array_length=$(( adapter_array_length - 4 - adapter_structure_length )) + done +} + +# ============================================================================= +# SMAPI Function: Virtual_Network_LAN_Access +# ============================================================================= +function Virtual_Network_LAN_Access +{ + # Define local variables + local i lan_name lan_owner access_op access_user promiscuity + + # Define info for parser + desc="Grant access to LAN" + required=(" -n | --name LAN name" \ + " -o | --owner LAN owner" \ + " -a | --access access operationr" \ + " : GRANT" \ + " : REVOKE" \ + " -i | --image target image") + optional=(" -p | --promis promiscuity" \ + " : NONPROMISCUOUS (default)" \ + " : PROMISCUOUS") + optional=() + opts="n:o:a:i:p:" + optl="name:,owner:,access:,image:,promis:" + usesparms="n" + + # Parse the command line + parseopts + + # Initialize optional variables + promiscuity="NONPROMISCUOUS" + + # Process options + for (( i = 0; i < ${#argv[@]}; i++ )) + do + case "${argv[i]}" in + -n | --name) + i=$(( i + 1 )) + lan_name="${argv[i]}" + ;; + + -o | --owner) + i=$(( i + 1 )) + lan_owner="${argv[i]}" + ;; + + -a | --access) + i=$(( i + 1 )) + access_op="${argv[i]}" + ;; + + -i | --image) + i=$(( i + 1 )) + access_user="${argv[i]}" + ;; + + -p | --promis) + i=$(( i + 1 )) + promiscuity="${argv[i]}" + ;; + esac + done + + # Build and send the request + execute $(asciiz "${lan_name}") \ + $(asciiz "${lan_owner}") \ + $(asciiz "${access_op}") \ + $(asciiz "${access_user}") \ + $(asciiz "${promiscuity}") + + # Tell user it was successful + echo "${access_user}'s access to ${lan_owner} ${lan_name} updated" +} + +# ============================================================================= +# SMAPI Function: Virtual_Network_LAN_Access_Query +# ============================================================================= +function Virtual_Network_LAN_Access_Query +{ + # Define local variables + local i lan_name lan_owner + + # Define info for parser + desc="Query access to LAN" + required=(" -n | --name LAN name" \ + " -o | --owner LAN owner") + optional=() + opts="n:o:" + optl="name:,owner:" + usesparms="n" + + # Parse the command line + parseopts + + # Process options + for (( i = 0; i < ${#argv[@]}; i++ )) + do + case "${argv[i]}" in + -n | --name) + i=$(( i + 1 )) + lan_name="${argv[i]}" + ;; + + -o | --owner) + i=$(( i + 1 )) + lan_owner="${argv[i]}" + ;; + esac + done + + # Build and send the request + execute $(asciiz "${lan_name}") \ + $(asciiz "${lan_owner}") + + # Retrieve and show the returned array + showasciizarray ${#resp} +} + +# ============================================================================= +# SMAPI Function: Virtual_Network_LAN_Create +# ============================================================================= +function Virtual_Network_LAN_Create +{ + # Define local variables + local i lan_name lan_owner lan_type transport_type + + # Define info for parser + desc="Create a virtual LAN" + required=(" -n | --name lan name" \ + " -o | --owner lan owner" \ + " -t | --type lan type" \ + " : 1 = unrestricted Hipersocket LAN" \ + " : 2 = unrestricted QDIO LAN" \ + " : 3 = restricted Hipersocket LAN" \ + " : 4 = restricted QDIO LAN") + optional=(" -m | --mech transport mechanism" \ + " : 0 = Unspecified (IP assumed)" \ + " : 1 = IP" \ + " : 2 = Ethernet") + opts="n:o:t:m:" + optl="name:,owner:,type:,mech:" + usesparms="n" + + # Parse the command line + parseopts + + # Initialize optional variables + transport_type="0" + + # Process options + for (( i = 0; i < ${#argv[@]}; i++ )) + do + case "${argv[i]}" in + -n | --name) + i=$(( i + 1 )) + lan_name="${argv[i]}" + ;; + + -o | --owner) + i=$(( i + 1 )) + lan_owner="${argv[i]}" + ;; + + -t | --type) + i=$(( i + 1 )) + lan_type="${argv[i]}" + ;; + + -m | --mech) + i=$(( i + 1 )) + transport_type="${argv[i]}" + ;; + + -p | --path) + i=$(( i + 1 )) + channel_path_id="${argv[i]}" + ;; + esac + done + + # Build and send the request + execute $(string "${lan_name}") \ + $(string "${lan_owner}") \ + $(int1 "${lan_type}") \ + $(int1 "${transport_type}") + + # Tell user it was successful + echo "${lan_owner} ${lan_name} created" +} + +# ============================================================================= +# SMAPI Function: Virtual_Network_LAN_Delete +# ============================================================================= +function Virtual_Network_LAN_Delete +{ + # Define local variables + local i lan_name lan_owner + + # Define info for parser + desc="Delete a virtual LAN" + required=(" -n | --name lan name" \ + " -o | --owner lan owner") + optional=() + opts="n:o:" + optl="name:,owner:" + usesparms="n" + + # Parse the command line + parseopts + + # Process options + for (( i = 0; i < ${#argv[@]}; i++ )) + do + case "${argv[i]}" in + -n | --name) + i=$(( i + 1 )) + lan_name="${argv[i]}" + ;; + + -o | --owner) + i=$(( i + 1 )) + lan_owner="${argv[i]}" + ;; + esac + done + + # Build and send the request + execute $(string "${lan_name}") \ + $(string "${lan_owner}") + + # Tell user it was successful + echo "${lan_owner} ${lan_name} deleted" +} + +# ============================================================================= +# SMAPI Function: Virtual_Network_LAN_Query +# ============================================================================= +function Virtual_Network_LAN_Query +{ + # Define local variables + local i lan_name lan_owner lan_type + local lan_array_length lan_structure_length + local connected_adapter_array_length connected_adapter_structure_length + local adapter_owner image_device_number + + # Define info for parser + desc="Query a virtual LAN" + required=(" -n | --name lan name" \ + " -o | --owner lan owner") + optional=() + opts="n:o:" + optl="name:,owner:" + usesparms="n" + + # Parse the command line + parseopts + + # Process options + for (( i = 0; i < ${#argv[@]}; i++ )) + do + case "${argv[i]}" in + -n | --name) + i=$(( i + 1 )) + lan_name="${argv[i]}" + ;; + + -o | --owner) + i=$(( i + 1 )) + lan_owner="${argv[i]}" + ;; + esac + done + + # Build and send the request + execute $(string "${lan_name}") \ + $(string "${lan_owner}") + + # Retrieve the array length + get4 lan_array_length + + # Retrieve and process array entries + while [ ${lan_array_length} -gt 0 ] + do + # Retrieve the entry length + get4 lan_structure_length + + # Protect against empty entries + if [ ${lan_structure_length} -gt 0 ] + then + # Retrieve the entry fields + getstring lan_name + getstring lan_owner + get1 lan_type + + # Convert lan_type + case "${lan_type}" in + 1) lan_type="${lan_type} (Hipersocket)" ;; + 2) lan_type="${lan_type} (QDIO)" ;; + *) lan_type="${lan_type} (??)" ;; + esac + + # Show it to the user + echo "LAN:" + echo " Name: ${lan_name}" + echo " Owner: ${lan_owner}" + + # Retrieve the array length + get4 connected_adapter_array_length + + # Retrieve and process array entries + echo " Connections:" + while [ ${connected_adapter_array_length} -gt 0 ] + do + # Retrieve the entry length + get4 connected_adapter_structure_length + + # Protect against empty entries + if [ ${connected_adapter_structure_length} -gt 0 ] + then + # Retrieve the entry fields + getstring adapter_owner + getstring image_device_number + + # Show it to the user + printf " Adapter Owner: %-8s Address: %s\n" ${adapter_owner} ${image_device_number} + fi + + # Calculate remaining length (+4 for the "CPU_info_structure_length" itself) + connected_adapter_array_length=$(( connected_adapter_array_length - 4 - connected_adapter_structure_length )) + done + + echo + fi + + # Calculate remaining length (+4 for the "CPU_info_structure_length" itself) + lan_array_length=$(( lan_array_length - 4 - lan_structure_length )) + done +} + +# ============================================================================= +# SMAPI Function: Virtual_Network_OSA_Query +# ============================================================================= +function Virtual_Network_OSA_Query +{ + # Define local variables + local i keyword_parms + + # Define info for parser + desc="Queury real OSA devices" + required=() + optional=() + opts="" + optl="" + usesparms="n" + + # Parse the command line + parseopts + + # Build and send the request + execute + + # Show each entry until nothing left + while [ ${#resp} -gt 0 ] + do + getasciiz osa_info_structure + set -- ${osa_info_structure} + + # Show it to the user + echo "OSA Info:" + echo " Address: ${1}" + echo " Status: ${2}" + echo " Type: ${3}" + echo " Chpid: ${4}" + echo " Agent: ${5}" + echo + done +} + +# ============================================================================= +# SMAPI Function: Virtual_Network_VLAN_Query_Stats +# ============================================================================= +function Virtual_Network_VLAN_Query_Stats +{ + # Define local variables + local + + # Define info for parser + desc="Query virtual LAN statistics" + + # Build and send the request + execute_keywords + + # Retrieve the length of the returned array + getasciiz port_array_length + + # Retrieve and process array entries + while [ ${#resp} -gt 0 ] + do + # Retrieve entry fields + getasciiz port_name + getasciiz port_num + + echo "Port Info:" + echo " Port Name: ${port_name}" + echo " Port Number: ${port_num}" + echo " Segment Info:" + + getasciiz pseg_array_length + i=$(( ${#resp} - pseg_array_length * 2 )) + while [ ${#resp} -gt ${i} ] + do + getasciiz pseg_structure + set -- ${pseg_structure} + + echo " VLAN ID: ${1}" + echo " Received Frames: ${2}" + echo " Received Frames Discarded: ${3}" + echo " Transmitted Frames: ${4}" + echo " Transmitted Frames Discarded: ${5}" + echo + done + done + + # Retrieve the length of the returned array + getasciiz nic_array_length + + # Retrieve and process array entries + while [ ${#resp} -gt 0 ] + do + # Retrieve entry fields + getasciiz nic_name + getasciiz nic_num + + echo "NIC Info:" + echo " NIC Name: ${nic_name}" + echo " NIC Number: ${nic_num}" + echo " Segment Info:" + + getasciiz nseg_array_length + i=$(( ${#resp} - nseg_array_length * 2 )) + while [ ${#resp} -gt ${i} ] + do + getasciiz nseg_structure + set -- ${nseg_structure} + + echo " VLAN ID: ${1}" + echo " Received Frames: ${2}" + echo " Received Frames Discarded: ${3}" + echo " Transmitted Frames: ${4}" + echo " Transmitted Frames Discarded: ${5}" + echo + done + done +} + +# ============================================================================= +# SMAPI Function: Virtual_Network_Vswitch_Create +# ============================================================================= +function Virtual_Network_Vswitch_Create +{ + # Define local variables + local i switch_name real_device_address port_name + local controller_name connection_value queue_memory_limit + local routing_value transport_type vlan_id port_type + local update_system_config_indicator gvrp_value native_vlanid + local system_config_name system_config_type + local parm_disk_owner parm_disk_number parm_disk_password + local alt_system_config_name alt_system_config_type + local alt_parm_disk_owner alt_parm_disk_number alt_parm_disk_password + + # Define info for parser + desc="Create a virtual switch" + required=(" -s | --switch switch name") + optional=(" -a | --addr real device address" \ + " -p | --portname port name" \ + " -c | --ctlrname controller name" \ + " -v | --connval connection value" \ + " : 0 = Unspecified (defaults to 1)" \ + " : 1 = Activate" \ + " : 2 = Do not activate" \ + " -q | --queue queue memory limit" \ + " -r | --routing routing value" \ + " : 0 = Unspecified" \ + " : 1 = NONROUTER" \ + " : 2 = PRIROUTER" \ + " -t | --trans transport type" \ + " : 0 = Unspecified" \ + " : 1 = IP" \ + " : 2 = ETHERNET" \ + " -i | --id vlan id" \ + " : -1 = Unspecified" \ + " : 0 = UNAWARE" \ + " : 1-4096 = VLAN ID" \ + " -o | --port port type" \ + " : 0 = Unspecified" \ + " : 1 = ACCESS" \ + " : 2 = TRUNK" + " -u | --update update system config" \ + " : 0 = Unspecified (defaults to 1)" \ + " : 1 = Create only" \ + " : 2 = Create and add to system config" \ + " : 3 = Add to system config only" \ + " -g | --gvrp GVRP value" \ + " : 0 = Unspecified" \ + " : 1 = GVRP" \ + " : 2 = NOGVRP" \ + " -n | --native native VLAN ID" + " : -1 = Unspecified" \ + " : 1-4096 = VLAN ID" \ + " --confname system config name (default SYSTEM)" \ + " --conftype system config type (default CONFIG)" \ + " --parmowner parm disk owner (default MAINT)" \ + " --parmaddr parm disk address (default CF1)" \ + " --parmpass parm disk password (default \",\")" \ + " --altname alternate system config name (default SYSTEM)" \ + " --alttype alternate system config type (default CONFIG)" \ + " --altowner alternate parm disk owner (default MAINT)" \ + " --altaddr alternate parm disk address (default CF2)" \ + " --altpass alternate parm disk password (default \",\")") + opts="s:a:p:c:v:q:r:t:i:o:u:g:n:" + optl="switch:,addr:,portname:,ctlrname:,connval:,queue:,routing:,trans:,id:,port:,update:,gvrp:,native:" + optl="${optl},confname:,conftype:,parmowner:,parmaddr:,parmpass:" + optl="${optl},altname:,alttype:,altowner:,altaddr:,altpass:" + usesparms="n" + + # Parse the command line + parseopts + + # Initialize optional variables + real_device_address="" + port_name="" + controller_name="" + connection_value="0" + queue_memory_limit="-1" + routing_value="0" + transport_type="0" + vlan_id="-1" + port_type="0" + update_system_config_indicator="0" + gvrp_value="0" + native_vlanid="-1" + system_config_name="" + system_config_type="" + parm_disk_owner="" + parm_disk_number="" + parm_disk_password="" + alt_system_config_name="" + alt_system_config_type="" + alt_parm_disk_owner="" + alt_parm_disk_number="" + alt_parm_disk_password="" + + # Process options + for (( i = 0; i < ${#argv[@]}; i++ )) + do + case "${argv[i]}" in + -s | --switch) + i=$(( i + 1 )) + switch_name="${argv[i]}" + ;; + + -a | --addr) + i=$(( i + 1 )) + real_device_address="${argv[i]}" + ;; + + -p | --portname) + i=$(( i + 1 )) + port_name="${argv[i]}" + ;; + + -c | --ctlrname) + i=$(( i + 1 )) + controller_name="${argv[i]}" + ;; + + -v | --connval) + i=$(( i + 1 )) + connection_value="${argv[i]}" + ;; + + -q | --queue) + i=$(( i + 1 )) + queue_memory_limit="${argv[i]}" + ;; + + -r | --routing) + i=$(( i + 1 )) + routing_value="${argv[i]}" + ;; + + -t | --trans) + i=$(( i + 1 )) + transport_type="${argv[i]}" + ;; + + -i | --id) + i=$(( i + 1 )) + vlan_id="${argv[i]}" + ;; + + -o | --port_type) + i=$(( i + 1 )) + port_type="${argv[i]}" + ;; + + -u | --update) + i=$(( i + 1 )) + update_system_config_indicator="${argv[i]}" + ;; + + --confname) + i=$(( i + 1 )) + system_config_name="${argv[i]}" + ;; + + --conftype) + i=$(( i + 1 )) + system_config_type="${argv[i]}" + ;; + + --parmowner) + i=$(( i + 1 )) + parm_disk_owner="${argv[i]}" + ;; + + --parmaddr) + i=$(( i + 1 )) + parm_disk_number="${argv[i]}" + ;; + + --parmpass) + i=$(( i + 1 )) + parm_disk_password="${argv[i]}" + ;; + + --altname) + i=$(( i + 1 )) + alt_system_config_name="${argv[i]}" + ;; + + --alttype) + i=$(( i + 1 )) + alt_system_config_type="${argv[i]}" + ;; + + --altowner) + i=$(( i + 1 )) + alt_parm_disk_owner="${argv[i]}" + ;; + + --altaddr) + i=$(( i + 1 )) + alt_parm_disk_number="${argv[i]}" + ;; + + --altpass) + i=$(( i + 1 )) + alt_parm_disk_password="${argv[i]}" + ;; + + -g | --gvrp) + i=$(( i + 1 )) + gvrp_value="${argv[i]}" + ;; + + -n | --native) + i=$(( i + 1 )) + native_vlanid="${argv[i]}" + ;; + esac + done + + # Build and send the request + execute $(string "${switch_name}") \ + $(string "${real_device_address}") \ + $(string "${port_name}") \ + $(string "${controller_name}") \ + $(int1 "${connection_value}") \ + $(int4 "${queue_memory_limit}") \ + $(int1 "${routing_value}") \ + $(int1 "${transport_type}") \ + $(int4 "${vlan_id}") \ + $(int1 "${port_type}") \ + $(int1 "${update_system_config_indicator}") \ + $(string "${system_config_name}") \ + $(string "${system_config_type}") \ + $(string "${parm_disk_owner}") \ + $(string "${parm_disk_number}") \ + $(string "${parm_disk_password}") \ + $(string "${alt_system_config_name}") \ + $(string "${alt_system_config_type}") \ + $(string "${alt_parm_disk_owner}") \ + $(string "${alt_parm_disk_number}") \ + $(string "${alt_parm_disk_password}") \ + $(int1 "${gvrp_value}") \ + $(int4 "${native_vlanid}") + + # Tell user it was successful + echo "${switch_name} created" +} + +# ============================================================================= +# SMAPI Function: Virtual_Network_Vswitch_Create_Extended +# ============================================================================= +function Virtual_Network_Vswitch_Create_Extended +{ + # Define local variables + local + + # Define info for parser + desc="Create a virtual switch" + + # Build and send the request + execute_keywords + + # Tell user it was successful + echo "Virtual switch created" +} + +# ============================================================================= +# SMAPI Function: Virtual_Network_Vswitch_Delete +# ============================================================================= +function Virtual_Network_Vswitch_Delete +{ + # Define local variables + local i switch_name update_system_config_indicator + local system_config_name system_config_type + local parm_disk_owner parm_disk_number parm_disk_password + local alt_system_config_name alt_system_config_type + local alt_parm_disk_owner alt_parm_disk_number alt_parm_disk_password + + # Define info for parser + desc="Delete a virtual switch" + required=(" -s | --switch switch name") + optional=(" -u | --update update system config" \ + " : 0 = Unspecified (defaults to 1)" \ + " : 1 = Delete only" \ + " : 2 = Delete and remove from system config" \ + " : 3 = Remove from system config only" \ + " --confname system config name (default SYSTEM)" \ + " --conftype system config type (default CONFIG)" \ + " --parmowner parm disk owner (default MAINT)" \ + " --parmaddr parm disk address (default CF1)" \ + " --parmpass parm disk password (default \",\")" \ + " --altname alternate system config name (default SYSTEM)" \ + " --alttype alternate system config type (default CONFIG)" \ + " --altowner alternate parm disk owner (default MAINT)" \ + " --altaddr alternate parm disk address (default CF2)" \ + " --altpass alternate parm disk password (default \",\")") + opts="s:u:" + optl="switch:,update:" + optl="${optl},confname:,conftype:,parmowner:,parmaddr:,parmpass:" + optl="${optl},altname:,alttype:,altowner:,altaddr:,altpass:" + usesparms="n" + + # Parse the command line + parseopts + + # Initialize optional variables + update_system_config_indicator=0 + system_config_name="" + system_config_type="" + parm_disk_owner="" + parm_disk_number="" + parm_disk_password="" + alt_system_config_name="" + alt_system_config_type="" + alt_parm_disk_owner="" + alt_parm_disk_number="" + alt_parm_disk_password="" + + # Process options + for (( i = 0; i < ${#argv[@]}; i++ )) + do + case "${argv[i]}" in + -s | --switch) + i=$(( i + 1 )) + switch_name="${argv[i]}" + ;; + + -u | --update) + i=$(( i + 1 )) + update_system_config_indicator="${argv[i]}" + ;; + + --confname) + i=$(( i + 1 )) + system_config_name="${argv[i]}" + ;; + + --conftype) + i=$(( i + 1 )) + system_config_type="${argv[i]}" + ;; + + --parmowner) + i=$(( i + 1 )) + parm_disk_owner="${argv[i]}" + ;; + + --parmaddr) + i=$(( i + 1 )) + parm_disk_number="${argv[i]}" + ;; + + --parmpass) + i=$(( i + 1 )) + parm_disk_password="${argv[i]}" + ;; + + --altname) + i=$(( i + 1 )) + alt_system_config_name="${argv[i]}" + ;; + + --alttype) + i=$(( i + 1 )) + alt_system_config_type="${argv[i]}" + ;; + + --altowner) + i=$(( i + 1 )) + alt_parm_disk_owner="${argv[i]}" + ;; + + --altaddr) + i=$(( i + 1 )) + alt_parm_disk_number="${argv[i]}" + ;; + + --altpass) + i=$(( i + 1 )) + alt_parm_disk_password="${argv[i]}" + ;; + esac + done + + # Build and send the request + execute $(string "${switch_name}") \ + $(int1 "${update_system_config_indicator}") \ + $(string "${system_config_name}") \ + $(string "${system_config_type}") \ + $(string "${parm_disk_owner}") \ + $(string "${parm_disk_number}") \ + $(string "${parm_disk_password}") \ + $(string "${alt_system_config_name}") \ + $(string "${alt_system_config_type}") \ + $(string "${alt_parm_disk_owner}") \ + $(string "${alt_parm_disk_number}") \ + $(string "${alt_parm_disk_password}") + + # Tell user it was successful + echo "${switch_name} deleted" +} + +# ============================================================================= +# SMAPI Function: Virtual_Network_Vswitch_Delete_Extended +# ============================================================================= +function Virtual_Network_Vswitch_Delete_Extended +{ + # Define local variables + local + + # Define info for parser + desc="Delete a virtual switch" + + # Build and send the request + execute_keywords + + # Tell user it was successful + echo "Virtual switch deleted" +} + +# ============================================================================= +# SMAPI Function: Virtual_Network_Vswitch_Query +# ============================================================================= +function Virtual_Network_Vswitch_Query +{ + # Define local variables + local i + local vswitch_array_length vswitch_structure_length + local switch_name transport_type port_type switch_status + local queue_memory_limit vlan_id native_vlan_id mac_id + local gvrp_request_attribute gvrp_enabled_attribute + local real_device_array_length real_device_structure_length + local real_device_address controller_name port_name + local device_status device_error_status + local authorized_user_array_length authorized_user_structure_length + local grant_userid + local vlan_array_length vlan_structure_length + local user_vlan_id vlan_ids + local connected_adapter_array_length connected_adapter_structure_length + local adapter_owner image_device_number + + # Define info for parser + desc="Query a virtual switch" + required=(" -s | --switch switch name") + optional=() + opts="s:" + optl="switch:" + usesparms="n" + + # Parse the command line + parseopts + + # Process options + for (( i = 0; i < ${#argv[@]}; i++ )) + do + case "${argv[i]}" in + -s | --switch) + i=$(( i + 1 )) + switch_name="${argv[i]}" + ;; + esac + done + + # Build and send the request + execute $(string "${switch_name}") + + # Retrieve the array length + get4 vswitch_array_length + + # Retrieve and process array entries + while [ ${vswitch_array_length} -gt 0 ] + do + # Retrieve the entry length + get4 vswitch_structure_length + + # Protect against empty entries + if [ ${vswitch_structure_length} -gt 0 ] + then + # Retrieve the entry fields + getstring switch_name + get1 transport_type + get1 port_type + get4 queue_memory_limit + get1 routing_value + get4 vlan_id + get4 native_vlan_id + get8 mac_id + get1 gvrp_request_attribute + get1 gvrp_enabled_attribute + get1 switch_status + + # Convert transport_type + case "${transport_type}" in + 1) transport_type="${transport_type} (IP)" ;; + 2) transport_type="${transport_type} (Ethernet)" ;; + *) transport_type="${transport_type} (??)" ;; + esac + + # Convert port_type + case "${port_type}" in + 1) port_type="${port_type} (Access)" ;; + 2) port_type="${port_type} (Trunk)" ;; + *) port_type="${port_type} (??)" ;; + esac + + # Convert routing_value + case "${routing_value}" in + 1) routing_value="${routing_value} (NONROUTER)" ;; + 2) routing_value="${routing_value} (PRIROUTER)" ;; + *) routing_value="${routing_value} (??)" ;; + esac + + # Convert gvrp_request_attribute + case "${gvrp_request_attribute}" in + 1) gvrp_request_attribute="${gvrp_request_attribute} (Requested)" ;; + 2) gvrp_request_attribute="${gvrp_request_attribute} (Not requested)" ;; + *) gvrp_request_attribute="${gvrp_request_attribute} (??)" ;; + esac + + # Convert gvrp_enabled_attribute + case "${gvrp_enabled_attribute}" in + 1) gvrp_enabled_attribute="${gvrp_enabled_attribute} (Enabled)" ;; + 2) gvrp_enabled_attribute="${gvrp_enabled_attribute} (Not enabled)" ;; + *) gvrp_enabled_attribute="${gvrp_enabled_attribute} (??)" ;; + esac + + # Convert switch_status + case "${switch_status}" in + 1) switch_status="${switch_status} (Virtual switch defined)" ;; + 2) switch_status="${switch_status} (Controller not available)" ;; + 3) switch_status="${switch_status} (Operator intervention required)" ;; + 4) switch_status="${switch_status} (Disconnected)" ;; + 5) switch_status="${switch_status} (Virtual devices attached to controller)" ;; + 6) switch_status="${switch_status} (OSA initialization in progress)" ;; + 7) switch_status="${switch_status} (OSA device not ready)" ;; + 8) switch_status="${switch_status} (OSA device ready)" ;; + 9) switch_status="${switch_status} (OSA devices being detached)" ;; + 10) switch_status="${switch_status} (Virtual switch delete pending)" ;; + 11) switch_status="${switch_status} (Virtual switch failover recovering)" ;; + 12) switch_status="${switch_status} (Autorestart in progress)" ;; + *) switch_status="${switch_status} (??)" ;; + esac + + # Show it to the user + echo "VSWITCH:" + echo " Name: ${switch_name}" + echo " Transport type: ${transport_type}" + echo " Port type: ${port_type}" + echo " Queue memory limit: ${queue_memory_limit}" + echo " Routing value: ${routing_value}" + echo " VLAN ID: ${vlan_id}" + echo " Native VLAN ID: ${native_vlan_id}" + printf " Mac ID: %016x\n" "${mac_id}" + echo " GVRP request attributes: ${gvrp_request_attribute}" + echo " GVRP enabled attributes: ${gvrp_enabled_attribute}" + echo " Switch status: ${switch_status}" + + # Retrieve the array length + get4 real_device_array_length + + # Retrieve and process array entries + if [ ${real_device_array_length} -gt 0 ] + then + echo " Devices:" + fi + + while [ ${real_device_array_length} -gt 0 ] + do + # Retrieve the entry length + get4 real_device_structure_length + + # Protect against empty entries + if [ ${real_device_structure_length} -gt 0 ] + then + # Retrieve the entry fields + get4 real_device_address + getstring controller_name + getstring port_name + get1 device_status + get1 device_error_status + + # Convert device_status + case "${device_status}" in + 0) device_status="${device_status} (Device is not active)" ;; + 1) device_status="${device_status} (Device is active)" ;; + 2) device_status="${device_status} (Device is a backup device)" ;; + *) device_status="${device_status} (??)" ;; + esac + + # Convert device_error_status + case "${device_error_status}" in + 0) device_error_status="${device_error_status} (No error)" ;; + 1) device_error_status="${device_error_status} (Port name conflict)" ;; + 2) device_error_status="${device_error_status} (No layer 2 support)" ;; + 3) device_error_status="${device_error_status} (Real device does not exist)" ;; + 4) device_error_status="${device_error_status} (Real device is attached elsewhere)" ;; + 5) device_error_status="${device_error_status} (Real device is not QDIO OSA-E)" ;; + 6) device_error_status="${device_error_status} (Initialization error)" ;; + 7) device_error_status="${device_error_status} (Stalled OSA)" ;; + 8) device_error_status="${device_error_status} (Stalled controller)" ;; + 9) device_error_status="${device_error_status} (Controller connection severed)" ;; + 10) device_error_status="${device_error_status} (Primary or secondary routing conflict)" ;; + 11) device_error_status="${device_error_status} (Device is offline)" ;; + 12) device_error_status="${device_error_status} (Device was detached)" ;; + 13) device_error_status="${device_error_status} (IP/Ethernet type mismatch)" ;; + 14) device_error_status="${device_error_status} (Insufficient memory in controller virtual machine)" ;; + 15) device_error_status="${device_error_status} (TCP/IP configuration conflict)" ;; + *) device_error_status="${device_error_status} (??)" ;; + esac + + # Show it to the user + printf " Read device: %04x\n" "${real_device_address}" + echo " Controller name: ${controller_name}" + echo " Port name: ${port_name}" + echo " Device Status: ${device_status}" + echo " Device error status: ${device_error_status}" + fi + echo + + # Calculate remaining length (+4 for the "CPU_info_structure_length" itself) + real_device_array_length=$(( real_device_array_length - 4 - real_device_structure_length )) + done + + # Retrieve the array length + get4 authorized_user_array_length + + # Retrieve and process array entries + if [ ${authorized_user_array_length} -gt 0 ] + then + echo " Authorized users:" + fi + + while [ ${authorized_user_array_length} -gt 0 ] + do + # Retrieve the entry length + get4 authorized_user_structure_length + + # Protect against empty entries + if [ ${authorized_user_structure_length} -gt 0 ] + then + # Retrieve the entry fields + getstring grant_userid + + # Retrieve the array length + get4 vlan_array_length + + # Retrieve and process array entries + vlan_ids="" + while [ ${vlan_array_length} -gt 0 ] + do + # Retrieve the entry length + get4 vlan_structure_length + + # Protect against empty entries + if [ ${vlan_structure_length} -gt 0 ] + then + # Retrieve the entry fields + get4 user_vlan_id + + # Remember it + vlan_ids="${vlan_ids} ${user_vlan_id}" + fi + + # Calculate remaining length (+4 for the "CPU_info_structure_length" itself) + vlan_array_length=$(( vlan_array_length - 4 - vlan_structure_length )) + done + + # Show it to the user + printf " User: %-8s - VLAN IDs:%s\n" "${grant_userid}" "${vlan_ids}" + fi + + # Calculate remaining length (+4 for the "CPU_info_structure_length" itself) + authorized_user_array_length=$(( authorized_user_array_length - 4 - authorized_user_structure_length )) + done + + # Retrieve the array length + get4 connected_adapter_array_length + + # Retrieve and process array entries + if [ ${connected_adapter_array_length} -gt 0 ] + then + echo " Connections:" + fi + + while [ ${connected_adapter_array_length} -gt 0 ] + do + # Retrieve the entry length + get4 connected_adapter_structure_length + + # Protect against empty entries + if [ ${connected_adapter_structure_length} -gt 0 ] + then + # Retrieve the entry fields + getstring adapter_owner + getstring image_device_number + + # Show it to the user + printf " Adapter owner: %-8s - Device number: %s\n" "${adapter_owner}" "${image_device_number}" + fi + + # Calculate remaining length (+4 for the "CPU_info_structure_length" itself) + connected_adapter_array_length=$(( connected_adapter_array_length - 4 - connected_adapter_structure_length )) + done + + echo + fi + + # Calculate remaining length (+4 for the "CPU_info_structure_length" itself) + vswitch_array_length=$(( vswitch_array_length - 4 - vswitch_structure_length )) + done +} + +# ============================================================================= +# SMAPI Function: Virtual_Network_Vswitch_Query_Extended +# ============================================================================= +function Virtual_Network_Vswitch_Query_Extended +{ + # Define local variables + local + + # Define info for parser + desc="Query virtual switch information" + + # Build and send the request + execute_keywords + + # Retrieve vswitch count + getasciiz vswitch_count + + for (( i = 0; i < vswitch_count; i++ )) + do + getasciiz vswitch_structure_length + getasciiz vswitch_attr_count + + echo "VSWITCH Info:" + echo + + getasciiz switch_name + getasciiz transport_type + getasciiz port_type + getasciiz queue_memory_limit + getasciiz routing_value + getasciiz vlan_awareness + getasciiz vlan_id + getasciiz native_vlan_id + getasciiz mac_id + getasciiz gvrp_request_attribute + getasciiz gvrp_enabled_attribute + getasciiz switch_status + getasciiz link_ag + getasciiz lag_interval + getasciiz lag_group + getasciiz ip_timeout + getasciiz switch_type + getasciiz isolation_status + getasciiz mac_protect + getasciiz user_port_based + if [ ${vswitch_attr_count} -gt 20 ] + then + getasciiz vlan_counters + fi + + + # Convert switch_status + case "${switch_status}" in + 1) switch_status="${switch_status} (Virtual switch defined)" ;; + 2) switch_status="${switch_status} (Controller not available)" ;; + 3) switch_status="${switch_status} (Operator intervention required)" ;; + 4) switch_status="${switch_status} (Disconnected)" ;; + 5) switch_status="${switch_status} (Virtual devices attached to controller)" ;; + 6) switch_status="${switch_status} (OSA initialization in progress)" ;; + 7) switch_status="${switch_status} (OSA device not ready)" ;; + 8) switch_status="${switch_status} (OSA device ready)" ;; + 9) switch_status="${switch_status} (OSA devices being detached)" ;; + 10) switch_status="${switch_status} (Virtual switch delete pending)" ;; + 11) switch_status="${switch_status} (Virtual switch failover recovering)" ;; + 12) switch_status="${switch_status} (Autorestart in progress)" ;; + *) switch_status="${switch_status} (??)" ;; + esac + + echo " Attributes:" + echo + echo " Switch Name: ${switch_name}" + echo " Transport Type: ${transport_type}" + echo " Port Type: ${port_type}" + echo " Queue Memory Limit: ${queue_memory_limit}" + echo " Routing Value: ${routing_value}" + echo " VLAN Awareness: ${vlan_awareness}" + echo " VLAN ID: ${vlan_id}" + echo " Native VLAN ID: ${native_vlan_id}" + echo " MAC ID: ${mac_id}" + echo " GVRP Request Attribute: ${gvrp_request_attribute}" + echo " GVRP Enabled Attribute: ${gvrp_enabled_attribute}" + echo " Switch Status: ${switch_status}" + echo " Link Aggregation: ${link_ag}" + echo " Link Aggregation Interval: ${lag_interval}" + echo " IP Timeout: ${ip_timeout}" + echo " Switch Type: ${switch_type}" + echo " Isolation Status: ${isolation_status}" + echo " MAC Protect: ${mac_protect}" + echo " User Port Based: ${user_port_based}" + echo " VLAN Counters: ${vlan_counters}" + echo + + getasciiz real_device_count + + echo " Device Info:" + echo + + for (( j = 0; j < real_device_count; j++ )) + do + getasciiz real_device_info_structure + set -- ${real_device_info_structure} + + device_status="${5}" + device_error_status="${6}" + + # Convert device_status + case "${device_status}" in + 0) device_status="${device_status} (Device is not active)" ;; + 1) device_status="${device_status} (Device is active)" ;; + 2) device_status="${device_status} (Device is a backup device)" ;; + *) device_status="${device_status} (??)" ;; + esac + + # Convert device_error_status + case "${device_error_status}" in + 0) device_error_status="${device_error_status} (No error)" ;; + 1) device_error_status="${device_error_status} (Port name conflict)" ;; + 2) device_error_status="${device_error_status} (No layer 2 support)" ;; + 3) device_error_status="${device_error_status} (Real device does not exist)" ;; + 4) device_error_status="${device_error_status} (Real device is attached elsewhere)" ;; + 5) device_error_status="${device_error_status} (Real device is not QDIO OSA-E)" ;; + 6) device_error_status="${device_error_status} (Initialization error)" ;; + 7) device_error_status="${device_error_status} (Stalled OSA)" ;; + 8) device_error_status="${device_error_status} (Stalled controller)" ;; + 9) device_error_status="${device_error_status} (Controller connection severed)" ;; + 10) device_error_status="${device_error_status} (Primary or secondary routing conflict)" ;; + 11) device_error_status="${device_error_status} (Device is offline)" ;; + 12) device_error_status="${device_error_status} (Device was detached)" ;; + 13) device_error_status="${device_error_status} (IP/Ethernet type mismatch)" ;; + 14) device_error_status="${device_error_status} (Insufficient memory in controller machine)" ;; + 15) device_error_status="${device_error_status} (TCP/IP configuration conflict)" ;; + 16) device_error_status="${device_error_status} (No link aggregation support)" ;; + 17) device_error_status="${device_error_status} (OSA-E attribute mismatch)" ;; + 18) device_error_status="${device_error_status} (Reserved for future use)" ;; + 19) device_error_status="${device_error_status} (OSA-E is not ready)" ;; + 20) device_error_status="${device_error_status} (Reserved for future use)" ;; + 21) device_error_status="${device_error_status} (Attempting restart for device)" ;; + 22) device_error_status="${device_error_status} (Error dedicating device)" ;; + 23) device_error_status="${device_error_status} (Device state is invalid)" ;; + 24) device_error_status="${device_error_status} (Port number is invalid for device)" ;; + 25) device_error_status="${device_error_status} (No OSA connection isolation)" ;; + 26) device_error_status="${device_error_status} (Reserved for future use)" ;; + 27) device_error_status="${device_error_status} (Reserved for future use)" ;; + *) device_error_status="${device_error_status} (??)" ;; + esac + + echo " RDEV: ${1}" + echo " VDEV: ${2}" + echo " Controller Name: ${3}" + echo " Port Name: ${4}" + echo " Status: ${device_status}" + echo " Error Status: ${device_error_status}" + echo + done + + getasciiz authorized_user_count + + echo " Authorized User Info:" + echo + + for (( j = 0; j < authorized_user_count; j++ )) + do + getasciiz authorized_user_structure + set -- ${authorized_user_structure} + + echo " Port Number: ${1}" + echo " Userid: ${2}" + echo " Promiscuous Mode: ${3}" + echo " OSD Simulation: ${4}" + + getasciiz vlan_count + + echo " VLAN Info:" + echo + + for (( k = 0; k < vlan_count; k++ )) + do + getasciiz user_vlan_id + echo " VLAN ID: ${user_vlan_id}" + done + echo + done + + getasciiz connected_adapter_count + + echo " Connected Adapter Info:" + echo + + for (( j = 0; j < connected_adapter_count; j++ )) + do + getasciiz connected_adapter_structure + set -- ${connected_adapter_structure} + + echo " Adapter Owner: ${1}" + echo " Virtual Device: ${2}" + echo " MAC Address: ${3}" + echo " Adapter Type: ${4}" + echo + done + + getasciiz uplink_nic_count + + echo " Uplink Nic Info:" + echo + + for (( j = 0; j < uplink_nic_count; j++ )) + do + getasciiz uplink_nic_structure + set -- ${uplink_nic_structure} + + uplink_nic_error_status="${3}" + + # Convert uplink_nic_error_status + case "${uplink_nic_error_status}" in + 0) uplink_nic_error_status="${uplink_nic_error_status} (No error)" ;; + 1) uplink_nic_error_status="${uplink_nic_error_status} (Userid not logged on)" ;; + 2) uplink_nic_error_status="${uplink_nic_error_status} (Not authorized)" ;; + 3) uplink_nic_error_status="${uplink_nic_error_status} (VDEV does not exist)" ;; + 4) uplink_nic_error_status="${uplink_nic_error_status} (VDEV is attached elsewhere)" ;; + 5) uplink_nic_error_status="${uplink_nic_error_status} (VDEV not compatible type)" ;; + 6) uplink_nic_error_status="${uplink_nic_error_status} (VLAN conflict)" ;; + 7) uplink_nic_error_status="${uplink_nic_error_status} (No MAC address)" ;; + 8) uplink_nic_error_status="${uplink_nic_error_status} (Not managed)" ;; + 9) uplink_nic_error_status="${uplink_nic_error_status} (Port error)" ;; + 13) uplink_nic_error_status="${uplink_nic_error_status} (Type mismatch)" ;; + 255) uplink_nic_error_status="${uplink_nic_error_status} (unknown error)" ;; + *) uplink_nic_error_status="${uplink_nic_error_status} (??)" ;; + esac + + echo " Userid: ${1}" + echo " VDEV: ${2}" + echo " Error Status: ${uplink_nic_error_status}" + echo + done + done +} + +# ============================================================================= +# SMAPI Function: Virtual_Network_Vswitch_Query_Stats +# ============================================================================= +function Virtual_Network_Vswitch_Query_Stats +{ + # Define local variables + local + + # Define info for parser + desc="Query virtual switch stats" + + # Build and send the request + execute_keywords + + # Retrieve the length of the returned array + getasciiz vswitch_array_length + + # Retrieve and process array entries + while [ ${#resp} -gt 0 ] + do + # Retrieve entry fields + getasciiz switch_name + + echo "Port Info:" + echo + + echo " Switch Name: ${switch_name}" + echo + + echo " Segment Info:" + echo + + getasciiz segment_array_length + + i=$(( ${#resp} - segment_array_length * 2 )) + while [ ${#resp} -gt ${i} ] + do + getasciiz segment_structure + set -o noglob + set -- ${segment_structure} + set +o noglob + + echo " VLAN ID: ${1}" + echo " Received Frames: ${2}" + echo " Received Frames Discarded: ${3}" + echo " Transmitted Frames: ${4}" + echo " Transmitted Frames Discarded: ${5}" + echo " Activated TOD: ${6}" + echo " Config Update TOD: ${7}" + echo " VLAN Interfaces: ${8}" + echo " VLAN Deletes: ${9}" + shift 9 + echo " Device Type: ${1}" + echo " Device Address: ${2}" + echo " Device Status: ${3}" + echo + done + done +} + +# ============================================================================= +# SMAPI Function: Virtual_Network_Vswitch_Set +# ============================================================================= +function Virtual_Network_Vswitch_Set +{ + # Define local variables + local i switch_name real_device_address port_name + + local i switch_name grant_userid user_vlan_id revoke_userid + local real_device_address port_name controller_name + local connection_value queue_memory_limit routing_value + local port_type update_system_config_indicator + local gvrp_value mac_id + local system_config_name system_config_type + local parm_disk_owner parm_disk_number parm_disk_password + local alt_system_config_name alt_system_config_type + local alt_parm_disk_owner alt_parm_disk_number alt_parm_disk_password + + # Define info for parser + desc="Change configuration of a virtual switch" + required=(" -s | --switch switch name") + optional=(" -g | --grant userid to add to the access list" \ + " -i | --id VLAN ID(s)" \ + " : up to 4 singles \"100 200 300\"" \ + " : and/or ranges \"100-300 400\"" \ + " -k | --revoke userid to remove from the access list" \ + " -a | --addr real device address" \ + " -p | --portname port name" \ + " -c | --ctlrname controller name" \ + " -v | --connval connection value" \ + " : 0 = Unspecified (defaults to 1)" \ + " : 1 = Activate" \ + " : 2 = Do not activate" \ + " -q | --queue queue memory limit" \ + " -r | --routing routing value" \ + " : 0 = Unspecified" \ + " : 1 = NONROUTER" \ + " : 2 = PRIROUTER" \ + " -o | --port port type" \ + " : 0 = Unspecified" \ + " : 1 = ACCESS" \ + " : 2 = TRUNK" + " -u | --update update system config" \ + " : 0 = Unspecified (defaults to 1)" \ + " : 1 = Update only" \ + " : 2 = Update active and system config" \ + " : 3 = Update system config only" \ + " -g | --gvrp GVRP value" \ + " : 0 = Unspecified" \ + " : 1 = GVRP" \ + " : 2 = NOGVRP" \ + " -m | --mac MAC ID" \ + " --confname system config name (default SYSTEM)" \ + " --conftype system config type (default CONFIG)" \ + " --parmowner parm disk owner (default MAINT)" \ + " --parmaddr parm disk address (default CF1)" \ + " --parmpass parm disk password (default \",\")" \ + " --altname alternate system config name (default SYSTEM)" \ + " --alttype alternate system config type (default CONFIG)" \ + " --altowner alternate parm disk owner (default MAINT)" \ + " --altaddr alternate parm disk address (default CF2)" \ + " --altpass alternate parm disk password (default \",\")") + opts="s:g:i:k:a:p:c:v:q:r:o:u:g:m:" + optl="switch:,grant:,id:,revoke:,addr:,portname:,ctlrname:,connval:,queue:,routing:,port:,update:,gvrp:,native:" + optl="${optl},confname:,conftype:,parmowner:,parmaddr:,parmpass:" + optl="${optl},altname:,alttype:,altowner:,altaddr:,altpass:" + usesparms="n" + + # Parse the command line + parseopts + + # Initialize optional variables + grant_userid="" + user_vlan_id="" + revoke_userid="" + real_device_address="" + port_name="" + controller_name="" + connection_value="0" + queue_memory_limit="-1" + routing_value="0" + port_type="0" + update_system_config_indicator="0" + gvrp_value="0" + mac_id="" + system_config_name="" + system_config_type="" + parm_disk_owner="" + parm_disk_number="" + parm_disk_password="" + alt_system_config_name="" + alt_system_config_type="" + alt_parm_disk_owner="" + alt_parm_disk_number="" + alt_parm_disk_password="" + + # Process options + for (( i = 0; i < ${#argv[@]}; i++ )) + do + case "${argv[i]}" in + -s | --switch) + i=$(( i + 1 )) + switch_name="${argv[i]}" + ;; + + -g | --grant) + i=$(( i + 1 )) + grant_userid="${argv[i]}" + ;; + + -i | --id) + i=$(( i + 1 )) + user_vlan_id="${argv[i]}" + ;; + + -k| --revoke) + i=$(( i + 1 )) + revoke_userid="${argv[i]}" + ;; + + -a | --addr) + i=$(( i + 1 )) + real_device_address="${argv[i]}" + ;; + + -p | --portname) + i=$(( i + 1 )) + port_name="${argv[i]}" + ;; + + -c | --ctlrname) + i=$(( i + 1 )) + controller_name="${argv[i]}" + ;; + + -v | --connval) + i=$(( i + 1 )) + connection_value="${argv[i]}" + ;; + + -q | --queue) + i=$(( i + 1 )) + queue_memory_limit="${argv[i]}" + ;; + + -r | --routing) + i=$(( i + 1 )) + routing_value="${argv[i]}" + ;; + + -o | --port_type) + i=$(( i + 1 )) + port_type="${argv[i]}" + ;; + + -u | --update) + i=$(( i + 1 )) + update_system_config_indicator="${argv[i]}" + ;; + + --confname) + i=$(( i + 1 )) + system_config_name="${argv[i]}" + ;; + + --conftype) + i=$(( i + 1 )) + system_config_type="${argv[i]}" + ;; + + --parmowner) + i=$(( i + 1 )) + parm_disk_owner="${argv[i]}" + ;; + + --parmaddr) + i=$(( i + 1 )) + parm_disk_number="${argv[i]}" + ;; + + --parmpass) + i=$(( i + 1 )) + parm_disk_password="${argv[i]}" + ;; + + --altname) + i=$(( i + 1 )) + alt_system_config_name="${argv[i]}" + ;; + + --alttype) + i=$(( i + 1 )) + alt_system_config_type="${argv[i]}" + ;; + + --altowner) + i=$(( i + 1 )) + alt_parm_disk_owner="${argv[i]}" + ;; + + --altaddr) + i=$(( i + 1 )) + alt_parm_disk_number="${argv[i]}" + ;; + + --altpass) + i=$(( i + 1 )) + alt_parm_disk_password="${argv[i]}" + ;; + + -g | --gvrp) + i=$(( i + 1 )) + gvrp_value="${argv[i]}" + ;; + + -m | --mac) + i=$(( i + 1 )) + mac_id="${argv[i]}" + ;; + esac + done + + # Build and send the request + execute $(string "${switch_name}") \ + $(string "${grant_userid}") \ + $(string "${user_vlan_id}") \ + $(string "${revoke_userid}") \ + $(string "${real_device_address}") \ + $(string "${port_name}") \ + $(string "${controller_name}") \ + $(int1 "${connection_value}") \ + $(int4 "${queue_memory_limit}") \ + $(int1 "${routing_value}") \ + $(int1 "${port_type}") \ + $(int1 "${update_system_config_indicator}") \ + $(string "${system_config_name}") \ + $(string "${system_config_type}") \ + $(string "${parm_disk_owner}") \ + $(string "${parm_disk_number}") \ + $(string "${parm_disk_password}") \ + $(string "${alt_system_config_name}") \ + $(string "${alt_system_config_type}") \ + $(string "${alt_parm_disk_owner}") \ + $(string "${alt_parm_disk_number}") \ + $(string "${alt_parm_disk_password}") \ + $(int1 "${gvrp_value}") \ + $(string "${mac_id}") + + # Tell user it was successful + echo "${switch_name} updated" +} + +# ============================================================================= +# SMAPI Function: Virtual_Network_Vswitch_Set_Extended +# ============================================================================= +function Virtual_Network_Vswitch_Set_Extended +{ + # Define local variables + local + + # Define info for parser + desc="Updated a virtual switch" + + # Build and send the request + execute_keywords + + # Tell user it was successful + echo "Virtual switch updated" +} + +# ============================================================================= +# SMAPI Function: VMRELOCATE +# ============================================================================= +function VMRELOCATE +{ + # Define local variables + local + + # Define info for parser + desc="Relocate a virtual machine" + + # Build and send the request + execute_keywords_no_check + + # Check for relocation failure + if [ ${reas} -eq 3000 ] + then + if [ ${retc} -eq 4 ] + then + getasciiz error_record + echo "VMRELOCATE TEST failed, error codes are:" + echo "${error_record}" + exit 1 + fi + + if [ ${retc} -eq 8 ] + then + getasciiz error_record + echo "VMRELOCATE MOVE failed, error codes are:" + echo "${error_record}" + exit 1 + fi + fi + + # Check for other errors + checkandfail + + # Tell user it was successful + echo "VMRELOCATE command sent" +} + +# ============================================================================= +# SMAPI Function: VMRELOCATE_Image_Attributes +# ============================================================================= +function VMRELOCATE_Image_Attributes +{ + # Define local variables + local + + # Define info for parser + desc="Modify relocation settings for image" + + # Build and send the request + execute_keywords + + # Tell user it was successful + echo "Settings updated" +} + +# ============================================================================= +# SMAPI Function: VMRELOCATE_Modify +# ============================================================================= +function VMRELOCATE_Modify +{ + # Define local variables + local + + # Define info for parser + desc="Modify relocation settings for image" + + # Build and send the request + execute_keywords_no_check + + # Check for relocation failure + if [ ${reas} -eq 3010 ] + then + if [ ${retc} -eq 8 ] + then + getasciiz error_record + echo "VMRELOCATE MODIFY failed, error codes are:" + echo "${error_record}" + exit 1 + fi + fi + + # Check for other errors + checkandfail + + # Tell user it was successful + echo "Relocation modified" +} + +# ============================================================================= +# SMAPI Function: VMRELOCATE_Status +# ============================================================================= +function VMRELOCATE_Status +{ + # Define local variables + local + + # Define info for parser + desc="Get status of in progress relocations" + + # Build and send the request + execute_keywords + + # Show each entry until nothing left + while [ ${#resp} -gt 0 ] + do + getasciiz status_structure + set -o noglob + set -- ${status_structure} + set +o noglob + + echo "Status:" + echo + + echo " Image: ${1}" + echo " Source System: ${2}" + echo " Destination System: ${3}" + echo " By: ${4}" + echo " Elapsed: ${5}" + echo " Status: ${6}" + echo + done +} + +# ============================================================================= +# SMAPI Function: VMRM_Configuration_Query +# ============================================================================= +function VMRM_Configuration_Query +{ + # Define local variables + local l configuration_file_name configuration_file_type + local configuration_dir_name + local configuration_file_length + + # Define info for parser + desc="Query VMRM configuration" + required=(" -n | --name file name" \ + " -t | --type file type" \ + " -d | --dir SFS directory name") + optional=() + opts="n:t:d:" + optl="name:,type:,dir:" + usesparms="n" + + # Parse the command line + parseopts + + # Process options + for (( i = 0; i < ${#argv[@]}; i++ )) + do + case "${argv[i]}" in + -n | --name) + i=$(( i + 1 )) + configuration_file_name="${argv[i]}" + ;; + + -t | --type) + i=$(( i + 1 )) + configuration_file_type="${argv[i]}" + ;; + + -d | --dir) + i=$(( i + 1 )) + configuration_dir_name="${argv[i]}" + ;; + esac + done + + # Build and send the request + execute $(string "${configuration_file_name}") \ + $(string "${configuration_file_type}") \ + $(string "${configuration_dir_name}") + + # Retrieve length + get4 configuration_file_length + + # Retrieve and show the returned array + showasciizarray ${configuration_file_length} +} + +# ============================================================================= +# SMAPI Function: VMRM_Configuration_Update +# ============================================================================= +function VMRM_Configuration_Update +{ + # Define local variables + local l configuration_file_name configuration_file_type + local configuration_dir_name configuration_file syncheck_only + local update_file + + # Define info for parser + desc="Update VMRM configuration" + required=(" -n | --name file name" \ + " -t | --type file type" \ + " -d | --dir SFS directory name") + optional=(" -c | --check syntax check only" \ + " : 0 = check and update" \ + " : 1 = check only") + opts="n:t:d:c:" + optl="name:,type:,dir:,check:" + usesparms="n" + + # Parse the command line + parseopts + + # Initialize optional variables + syncheck_only="0" + + # Process options + for (( i = 0; i < ${#argv[@]}; i++ )) + do + case "${argv[i]}" in + -n | --name) + i=$(( i + 1 )) + configuration_file_name="${argv[i]}" + ;; + + -t | --type) + i=$(( i + 1 )) + configuration_file_type="${argv[i]}" + ;; + + -d | --dir) + i=$(( i + 1 )) + configuration_dir_name="${argv[i]}" + ;; + + -c | --check) + i=$(( i + 1 )) + syncheck_only="${argv[i]}" + ;; + esac + done + + # Build update file from stdin + OIFS="${IFS}" + IFS=$'\n' + update_file="" + while read log_record + do + update_file="${update_file}$(asciiz """${log_record}""")" + done + IFS="${OIFS}" + + # Build and send the request + execute $(string "${configuration_file_name}") \ + $(string "${configuration_file_type}") \ + $(string "${configuration_dir_name}") \ + $(int1 "${syncheck_only}") \ + $(int4 ${#update_file}) \ + ${update_file} + + # Retrieve and show the returned array + showstringarray +} + +# ============================================================================= +# SMAPI Function: VMRM_Measurement_Query +# ============================================================================= +function VMRM_Measurement_Query +{ + # Define local variables + local query_timestamp file_spec le_timestamp + + # Define info for parser + desc="Query VMRM measurement values" + required=() + optional=() + opts="" + optl="" + usesparms="n" + + # Parse the command line + parseopts + + # Build and send the request + execute + + # Retrieve return values + getstring query_timestamp + getstring file_spec + getstring file_timestamp + + # Show them to the user + echo "Query timestamp: ${query_timestamp}" + echo "File spec: ${file_spec}" + echo "File timestamp: ${file_timestamp}" + echo + + # Retrieve and show the returned array + showstringarray +} + +# ============================================================================= +# SMAPI Function: Build_SMIUCV_helper +# ============================================================================= +function Build_SMIUCV_Helper +{ + # Define local variables + local opath + + which gcc >/dev/null 2>&1 + if [ "${?}" -ne 0 ] + then + echo "Unable to build smiucv helper ... can't find gcc" + exit 1 + fi + + opath=$(dirname "${0}") + gcc -O3 -Wl,-s -o "${opath}/smiucv" -x c - <response +|| +|| User and name are optional and will default to VSMREQIU and DMSRSRQU. +|| +|| Written by Leland Lucius +||======================================================================= +*/ + +#include +#include +#include +#include +#include +#include +#include +#include + +/* +|| Default remote IUCV user and name +*/ +#define IUCV_USER "VSMREQIU" +#define IUCV_NAME "DMSRSRQU" + +/* +|| Read data from the SMAPI server and write it to stdout +*/ +int +readwrite( int fd, void *ptr, int len ) +{ + unsigned char *buffer = (unsigned char *) ptr; + struct timeval timeout; + fd_set readfds; + int i; + int rc; + + /* + || Initialize timeout + */ + timeout.tv_sec = 30; + timeout.tv_usec = 0; + + /* + || Large responses will arrive in chunks + */ + for( i = 0; i < len; i += rc ) + { + /* + || Wait for timeout or data + */ + FD_ZERO( &readfds); + FD_SET( fd, &readfds ); + if( ( rc = select( fd + 1, &readfds, NULL, NULL, &timeout ) ) < 0 ) + { + fprintf( stderr, "select() failed: %d - %s\n", errno, strerror( errno ) ); + return 1; + } + else if( rc == 0 ) + { + fprintf( stderr, "Timeout waiting for response from remote\n" ); + return 1; + } + + /* + || Read it + */ + if( ( rc = recv( fd, &buffer[i], len - i, 0 ) ) < 0 ) + { + fprintf( stderr, "Error reading from socket: %d - %s\n", errno, strerror( errno ) ); + return 1; + } + else if( rc == 0 ) + { + fprintf( stderr, "Connection closed by remote\n" ); + return 1; + } + } + + /* + || Write to stdout + */ + if( write( fileno( stdout ), buffer, len ) != len ) + { + fprintf( stderr, "Error writing to stdout: %d - %s\n", errno, strerror( errno ) ); + return 1; + } + + return 0; +} + +int +main( int argc, char *argv[] ) +{ + struct sockaddr_iucv siu; + unsigned char *buffer = NULL; + char *user; + char *name; + int used = 0; + int bufsize = 0; + int fd = -1; + int rc = 0; + int len; + int reqid; + + /* + || Initialize sockaddr + */ + memset( &siu, 0, sizeof( siu ) ); + siu.siucv_family = AF_IUCV; + memset( &siu.siucv_nodeid, ' ', 8 ); + memset( &siu.siucv_user_id, ' ', 8 ); + memset( &siu.siucv_name, ' ', 8 ); + + /* + || Set userid...default or first command line argument + */ + user = IUCV_USER; + if( argc > 1 && argv[ 1 ] ) + { + user = argv[ 1 ]; + } + len = strlen( user ); + memcpy( &siu.siucv_user_id, user, ( len > 8 ? 8 : len ) ); + + /* + || Set name...default or second command line argument + */ + name = IUCV_NAME; + if( argc > 2 && argv[ 2 ] ) + { + name = argv[ 2 ]; + } + len = strlen( name ); + memcpy( &siu.siucv_name, name, ( len > 8 ? 8 : len ) ); + + /* + || Allocate an IUCV socket + */ + fd = socket( AF_IUCV, SOCK_STREAM, IPPROTO_IP ); + if( fd == -1 ) + { + fprintf( stderr, "Unable to create socket: %d - %s", errno, strerror( errno ) ); + rc = 1; + goto die; + } + + /* + || Bind it + */ + rc = bind( fd, (struct sockaddr *) &siu, sizeof( siu ) ); + if( rc < 0 ) + { + fprintf( stderr, "Unable to bind: %d - %s", errno, strerror( errno ) ); + rc = 1; + goto die; + } + + /* + || Connect to partner + */ + rc = connect( fd, (struct sockaddr *) &siu, sizeof( siu ) ); + if( rc == -1 ) + { + fprintf( stderr, "Unable to connect: %d - %s", errno, strerror( errno ) ); + rc = 1; + goto die; + } + + /* + || Read request into buffer + */ + do + { + if( used == bufsize ) + { + bufsize += 8192; + buffer = realloc( buffer, bufsize ); + if( buffer == NULL ) + { + fprintf( stderr, "Unable to alloc buffer: %d - %s\n", errno, strerror( errno ) ); + rc = 1; + goto die; + } + } + } while( read( fileno( stdin ), &buffer[ used++ ], 1 ) == 1 ); + + /* + || Send it to the server + */ + if( write( fd, buffer, --used ) != used ) + { + fprintf( stderr, "Error writing to socket: %d - %s\n", errno, strerror( errno ) ); + rc = 1; + goto die; + } + + /* + || Get the first request ID + */ + if( ( rc = readwrite( fd, &reqid, sizeof( reqid ) ) ) != 0 ) + { + goto die; + } + + /* + || Get the response length + */ + if( ( rc = readwrite( fd, &len, sizeof( len ) ) ) != 0 ) + { + goto die; + } + + /* + || Free original buffer and allocate a new one + */ + free( buffer ); + buffer = malloc( len ); + if( buffer == NULL ) + { + fprintf( stderr, "Unable to alloc buffer: %d - %s\n", errno, strerror( errno ) ); + rc = 1; + goto die; + } + + /* + || Get the response + */ + if( ( rc = readwrite( fd, buffer, len ) ) != 0 ) + { + goto die; + } + +die: + + /* + || Free the buffer + */ + if( buffer ) + { + free( buffer ); + } + + /* + || Kill the socket + */ + if( fd != -1 ) + { + shutdown( fd, SHUT_RDWR ); + close( fd ); + } + + return rc; +} +END_OF_SMIUCV + + if [ "${?}" -ne 0 ] + then + echo "Failed to build smiucv..." + exit 1 + fi + + echo "smiucv built as ${opath}/smiucv" + echo + echo "Make sure \"${opath}\" is included in PATH." +} + +# ============================================================================= +# Main +# ============================================================================= +function main +{ + # Define local variables + local i funcs + + # Read the global config file + [ -r /etc/smaclient.conf ] && . /etc/smaclient.conf + + # Override or supplement with personal config + [ -r ~/.smaclient ] && . ~/.smaclient + + # Environment variables provide final override + if [ ! -z "$SMHOST" ] + then + smhost="$SMHOST" + fi + + if [ ! -z "$SMUSER" ] + then + smuser="$SMUSER" + fi + + if [ ! -z "$SMPASS" ] + then + smpass="$SMPASS" + fi + + # Get SMAPI function name (may be the abbrev at this point) and remove + smfunc="${1}" + shift + + # Remember command arguments + argv=("${@}") + + # Define supported functions (long name MUST match SMAPI function name) + funcs=("smiucv Build_SMIUCV_Helper" \ + "andd Asynchronous_Notification_Disable_DM" \ + "aned Asynchronous_Notification_Enable_DM" \ + "anqd Asynchronous_Notification_Query_DM" \ + "ala Authorization_List_Add" \ + "alq Authorization_List_Query" \ + "alr Authorization_List_Remove" \ + # Check_Authorization (does not follow API format) + "dabd Delete_ABEND_Dump" + "dmltdfd Directory_Manager_Local_Tag_Define_DM" \ + "dmltdld Directory_Manager_Local_Tag_Delete_DM" \ + "dmltqd Directory_Manager_Local_Tag_Query_DM" \ + "dmltsd Directory_Manager_Local_Tag_Set_DM" \ + "dmsd Directory_Manager_Search_DM" \ + "dmtcd Directory_Manager_Task_Cancel_DM" \ + "esa Event_Stream_Add" \ + "es Event_Subscribe" \ + "eu Event_Unsubscribe" \ + "ia Image_Activate" \ + "iacq Image_Active_Configuration_Query" \ + "icdf Image_CPU_Define" \ + "icdfd Image_CPU_Define_DM" \ + "icdl Image_CPU_Delete" \ + "icdld Image_CPU_Delete_DM" \ + "icq Image_CPU_Query" \ + "icqd Image_CPU_Query_DM" \ + "icsmd Image_CPU_Set_Maximum_DM" \ + "icd Image_Create_DM" \ + "id Image_Deactivate" \ + "idau Image_Definition_Async_Updates" \ + "idcd Image_Definition_Create_DM" \ + "iddd Image_Definition_Delete_DM" \ + "idqd Image_Definition_Query_DM" \ + "idud Image_Definition_Update_DM" \ + "idd Image_Delete_DM" \ + "ided Image_Device_Dedicate" \ + "idedd Image_Device_Dedicate_DM" \ + "ider Image_Device_Reset" \ + "ideu Image_Device_Undedicate" \ + "ideud Image_Device_Undedicate_DM" \ + "idico Image_Disk_Copy" \ + "idicod Image_Disk_Copy_DM" \ + "idicr Image_Disk_Create" \ + "idicrd Image_Disk_Create_DM" \ + "idid Image_Disk_Delete" \ + "ididd Image_Disk_Delete_DM" \ + "idq Image_Disk_Query" \ + "idis Image_Disk_Share" \ + "idisd Image_Disk_Share_DM" \ + "idiu Image_Disk_Unshare" \ + "idiud Image_Disk_Unshare_DM" \ + "iidd Image_IPL_Delete_DM" \ + "iiqd Image_IPL_Query_DM" \ + "iisd Image_IPL_Set_DM" \ + "ild Image_Lock_DM" \ + "inqd Image_Name_Query_DM" \ + "ipsd Image_Password_Set_DM" \ + "iqat Image_Query_Activate_Time" \ + "iqd Image_Query_DM" \ + "ir Image_Recycle" \ + "ird Image_Replace_DM" \ + "iscdd Image_SCSI_Characteristics_Define_DM" \ + "iscqd Image_SCSI_Characteristics_Query_DM" \ + "isq Image_Status_Query" \ + "iud Image_Unlock_DM" \ + "iva Image_Volume_Add" \ + "ivd Image_Volume_Delete" \ + "ivs Image_Volume_Share" \ + "ivsdd Image_Volume_Space_Define_DM" \ + "ivsded Image_Volume_Space_Define_Extended_DM" \ + "ivsqd Image_Volume_Space_Query_DM" \ + "ivsqed Image_Volume_Space_Query_Extended_DM" \ + "ivsrd Image_Volume_Space_Remove_DM" \ + "md Metadata_Delete" \ + "mg Metadata_Get" \ + "ms Metadata_Set" \ + "nla Name_List_Add" \ + "nld Name_List_Destroy" \ + "nlq Name_List_Query" \ + "nlr Name_List_Remove" \ + "posva Page_or_Spool_Volume_Add" \ + "pabd Process_ABEND_Dump" \ + "pfcd Profile_Create_DM" \ + "pfdd Profile_Delete_DM" \ + "pfld Profile_Lock_DM" \ + "pfqd Profile_Query_DM" \ + "pfrd Profile_Replace_DM" \ + "pfud Profile_Unlock_DM" \ + "ptcd Prototype_Create_DM" \ + "ptdd Prototype_Delete_DM" \ + "ptnqd Prototype_Name_Query_DM" \ + "ptqd Prototype_Query_DM" \ + "ptrd Prototype_Replace_DM" \ + "qabd Query_ABEND_Dump" \ + "qad Query_All_DM" \ + "qafl Query_API_Functional_Level" \ + "qaod Query_Asynchronous_Operation_DM" \ + "qdmld Query_Directory_Manager_Level_DM" \ + "rr Response_Recovery" \ + "smaad Shared_Memory_Access_Add_DM" \ + "smaqd Shared_Memory_Access_Query_DM" \ + "smard Shared_Memory_Access_Remove_DM" \ + "smc Shared_Memory_Create" \ + "smd Shared_Memory_Delete" \ + "smq Shared_Memory_Query" \ + "smr Shared_Memory_Replace" \ + "sq SSI_Query" \ + "sicad Static_Image_Changes_Activate_DM" \ + "sicdd Static_Image_Changes_Deactivate_DM" \ + "sicid Static_Image_Changes_Immediate_DM" \ + "scsc System_Config_Syntax_Check" \ + "sdac System_Disk_Accessibility" \ + "sda System_Disk_Add" \ + "sdq System_Disk_Query" \ + "sffq System_FCP_Free_Query" \ + "sptd System_Performance_Threshold_Disable" \ + "spte System_Performance_Threshold_Enable" \ + "ssda System_SCSI_Disk_Add" \ + "ssdd System_SCSI_Disk_Delete" \ + "ssdq System_SCSI_Disk_Query" \ + "swq System_WWPN_Query" \ + "vccc Virtual_Channel_Connection_Create" \ + "vcccd Virtual_Channel_Connection_Create_DM" \ + "vccd Virtual_Channel_Connection_Delete" \ + "vccdd Virtual_Channel_Connection_Delete_DM" \ + "vnacl Virtual_Network_Adapter_Connect_LAN" \ + "vnacld Virtual_Network_Adapter_Connect_LAN_DM" \ + "vnacv Virtual_Network_Adapter_Connect_Vswitch" \ + "vnacvd Virtual_Network_Adapter_Connect_Vswitch_DM" \ + "vnacve Virtual_Network_Adapter_Connect_Vswitch_Extended" \ + "vnac Virtual_Network_Adapter_Create" \ + "vnacd Virtual_Network_Adapter_Create_DM" \ + "vnace Virtual_Network_Adapter_Create_Extended" \ + "vnaced Virtual_Network_Adapter_Create_Extended_DM" \ + "vnadl Virtual_Network_Adapter_Delete" \ + "vnadld Virtual_Network_Adapter_Delete_DM" \ + "vnadc Virtual_Network_Adapter_Disconnect" \ + "vnadcd Virtual_Network_Adapter_Disconnect_DM" \ + "vnaq Virtual_Network_Adapter_Query" \ + "vnla Virtual_Network_LAN_Access" \ + "vnlaq Virtual_Network_LAN_Access_Query" \ + "vnlc Virtual_Network_LAN_Create" \ + "vnld Virtual_Network_LAN_Delete" \ + "vnlq Virtual_Network_LAN_Query" \ + "vnoq Virtual_Network_OSA_Query" \ + "vnvlqs Virtual_Network_VLAN_Query_Stats" \ + "vnvc Virtual_Network_Vswitch_Create" \ + "vnvce Virtual_Network_Vswitch_Create_Extended" \ + "vnvd Virtual_Network_Vswitch_Delete" \ + "vnvde Virtual_Network_Vswitch_Delete_Extended" \ + "vnvq Virtual_Network_Vswitch_Query" \ + "vnvqe Virtual_Network_Vswitch_Query_Extended" \ + "vnvsqs Virtual_Network_Vswitch_Query_Stats" \ + "vnvs Virtual_Network_Vswitch_Set" \ + "vnvse Virtual_Network_Vswitch_Set_Extended" \ + "v VMRELOCATE" \ + "via VMRELOCATE_Image_Attributes" \ + "vm VMRELOCATE_Modify" \ + "vs VMRELOCATE_Status" \ + "vcq VMRM_Configuration_Query" \ + "vcu VMRM_Configuration_Update" \ + "vmq VMRM_Measurement_Query" \ + "") + + # Search function array and invoke handler if valid function specified + for (( i = 0; i < ${#funcs[@]} - 1; i++ )) + do + set -- ${funcs[i]} + + if [ "${smfunc}" == "${1}" ] + then + smfunc="${2}" + fi + + if [ "${smfunc}" == "${2}" ] + then + ${2} + return + fi + done + + # Introduce ourselves + echo "smaclient: z/VM SMAPI client - v${verrel}" + echo + + # Complain about missing or invalid function + if [ -z "${smfunc}" ] + then + echo "Function not specified as first argument" + else + echo "Unrecognized function \"${smfunc}\"" + fi + + # Help out the user a little + echo + echo "Available functions:" + echo + printf " %-50s %-8s %s\n" "Function name" "Abbrev" + for (( i = 0; i < ${#funcs[@]}; i++ )) + do + set -- ${funcs[i]} + printf " %-50s %-8s %s\n" "${2}" "${1}" + done + + exit 1 +} + +# Invoke main function +main "${@}" + +exit 0 diff --git a/smaclient-1.1-helper.patch b/smaclient-1.1-helper.patch new file mode 100644 index 0000000..b1338c3 --- /dev/null +++ b/smaclient-1.1-helper.patch @@ -0,0 +1,296 @@ +--- smaclient.old 2015-08-11 16:24:15.468078559 +0200 ++++ smaclient 2015-08-11 16:29:54.163066653 +0200 +@@ -9954,292 +9954,7 @@ + # ============================================================================= + function Build_SMIUCV_Helper + { +- # Define local variables +- local opath +- +- which gcc >/dev/null 2>&1 +- if [ "${?}" -ne 0 ] +- then +- echo "Unable to build smiucv helper ... can't find gcc" +- exit 1 +- fi +- +- opath=$(dirname "${0}") +- gcc -O3 -Wl,-s -o "${opath}/smiucv" -x c - <response +-|| +-|| User and name are optional and will default to VSMREQIU and DMSRSRQU. +-|| +-|| Written by Leland Lucius +-||======================================================================= +-*/ +- +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +- +-/* +-|| Default remote IUCV user and name +-*/ +-#define IUCV_USER "VSMREQIU" +-#define IUCV_NAME "DMSRSRQU" +- +-/* +-|| Read data from the SMAPI server and write it to stdout +-*/ +-int +-readwrite( int fd, void *ptr, int len ) +-{ +- unsigned char *buffer = (unsigned char *) ptr; +- struct timeval timeout; +- fd_set readfds; +- int i; +- int rc; +- +- /* +- || Initialize timeout +- */ +- timeout.tv_sec = 30; +- timeout.tv_usec = 0; +- +- /* +- || Large responses will arrive in chunks +- */ +- for( i = 0; i < len; i += rc ) +- { +- /* +- || Wait for timeout or data +- */ +- FD_ZERO( &readfds); +- FD_SET( fd, &readfds ); +- if( ( rc = select( fd + 1, &readfds, NULL, NULL, &timeout ) ) < 0 ) +- { +- fprintf( stderr, "select() failed: %d - %s\n", errno, strerror( errno ) ); +- return 1; +- } +- else if( rc == 0 ) +- { +- fprintf( stderr, "Timeout waiting for response from remote\n" ); +- return 1; +- } +- +- /* +- || Read it +- */ +- if( ( rc = recv( fd, &buffer[i], len - i, 0 ) ) < 0 ) +- { +- fprintf( stderr, "Error reading from socket: %d - %s\n", errno, strerror( errno ) ); +- return 1; +- } +- else if( rc == 0 ) +- { +- fprintf( stderr, "Connection closed by remote\n" ); +- return 1; +- } +- } +- +- /* +- || Write to stdout +- */ +- if( write( fileno( stdout ), buffer, len ) != len ) +- { +- fprintf( stderr, "Error writing to stdout: %d - %s\n", errno, strerror( errno ) ); +- return 1; +- } +- +- return 0; +-} +- +-int +-main( int argc, char *argv[] ) +-{ +- struct sockaddr_iucv siu; +- unsigned char *buffer = NULL; +- char *user; +- char *name; +- int used = 0; +- int bufsize = 0; +- int fd = -1; +- int rc = 0; +- int len; +- int reqid; +- +- /* +- || Initialize sockaddr +- */ +- memset( &siu, 0, sizeof( siu ) ); +- siu.siucv_family = AF_IUCV; +- memset( &siu.siucv_nodeid, ' ', 8 ); +- memset( &siu.siucv_user_id, ' ', 8 ); +- memset( &siu.siucv_name, ' ', 8 ); +- +- /* +- || Set userid...default or first command line argument +- */ +- user = IUCV_USER; +- if( argc > 1 && argv[ 1 ] ) +- { +- user = argv[ 1 ]; +- } +- len = strlen( user ); +- memcpy( &siu.siucv_user_id, user, ( len > 8 ? 8 : len ) ); +- +- /* +- || Set name...default or second command line argument +- */ +- name = IUCV_NAME; +- if( argc > 2 && argv[ 2 ] ) +- { +- name = argv[ 2 ]; +- } +- len = strlen( name ); +- memcpy( &siu.siucv_name, name, ( len > 8 ? 8 : len ) ); +- +- /* +- || Allocate an IUCV socket +- */ +- fd = socket( AF_IUCV, SOCK_STREAM, IPPROTO_IP ); +- if( fd == -1 ) +- { +- fprintf( stderr, "Unable to create socket: %d - %s", errno, strerror( errno ) ); +- rc = 1; +- goto die; +- } +- +- /* +- || Bind it +- */ +- rc = bind( fd, (struct sockaddr *) &siu, sizeof( siu ) ); +- if( rc < 0 ) +- { +- fprintf( stderr, "Unable to bind: %d - %s", errno, strerror( errno ) ); +- rc = 1; +- goto die; +- } +- +- /* +- || Connect to partner +- */ +- rc = connect( fd, (struct sockaddr *) &siu, sizeof( siu ) ); +- if( rc == -1 ) +- { +- fprintf( stderr, "Unable to connect: %d - %s", errno, strerror( errno ) ); +- rc = 1; +- goto die; +- } +- +- /* +- || Read request into buffer +- */ +- do +- { +- if( used == bufsize ) +- { +- bufsize += 8192; +- buffer = realloc( buffer, bufsize ); +- if( buffer == NULL ) +- { +- fprintf( stderr, "Unable to alloc buffer: %d - %s\n", errno, strerror( errno ) ); +- rc = 1; +- goto die; +- } +- } +- } while( read( fileno( stdin ), &buffer[ used++ ], 1 ) == 1 ); +- +- /* +- || Send it to the server +- */ +- if( write( fd, buffer, --used ) != used ) +- { +- fprintf( stderr, "Error writing to socket: %d - %s\n", errno, strerror( errno ) ); +- rc = 1; +- goto die; +- } +- +- /* +- || Get the first request ID +- */ +- if( ( rc = readwrite( fd, &reqid, sizeof( reqid ) ) ) != 0 ) +- { +- goto die; +- } +- +- /* +- || Get the response length +- */ +- if( ( rc = readwrite( fd, &len, sizeof( len ) ) ) != 0 ) +- { +- goto die; +- } +- +- /* +- || Free original buffer and allocate a new one +- */ +- free( buffer ); +- buffer = malloc( len ); +- if( buffer == NULL ) +- { +- fprintf( stderr, "Unable to alloc buffer: %d - %s\n", errno, strerror( errno ) ); +- rc = 1; +- goto die; +- } +- +- /* +- || Get the response +- */ +- if( ( rc = readwrite( fd, buffer, len ) ) != 0 ) +- { +- goto die; +- } +- +-die: +- +- /* +- || Free the buffer +- */ +- if( buffer ) +- { +- free( buffer ); +- } +- +- /* +- || Kill the socket +- */ +- if( fd != -1 ) +- { +- shutdown( fd, SHUT_RDWR ); +- close( fd ); +- } +- +- return rc; +-} +-END_OF_SMIUCV +- +- if [ "${?}" -ne 0 ] +- then +- echo "Failed to build smiucv..." +- exit 1 +- fi +- +- echo "smiucv built as ${opath}/smiucv" +- echo +- echo "Make sure \"${opath}\" is included in PATH." ++ exit 0 + } + + # ============================================================================= diff --git a/smaclient.spec b/smaclient.spec new file mode 100644 index 0000000..3f4f5db --- /dev/null +++ b/smaclient.spec @@ -0,0 +1,52 @@ +Name: smaclient +Version: 1.1 +Release: 3%{?dist} +Summary: Provides access to z/VM System Management functions + +License: Artistic 2.0 +URL: http://download.sinenomine.net/smaclient/ +Source0: http://download.sinenomine.net/smaclient/%{name}-%{version} +# The helper source code was extracted from upstream's script. +Source1: smiucv.c +# Remove helper's code from the script since it's provided as a separate file +Patch0: %{name}-%{version}-helper.patch +Requires: coreutils util-linux vim-common + +%description +smaclient is a tool which provides a line-mode interface to the z/VM System +Management API (SMAPI) for most Unix-compatible systems such as Linux. +Smaclient can exercise all the VM management interfaces to create, modify and +destroy virtual machines without ever logging into z/VM. + +%prep +%setup -q -T -c +cp -p %{SOURCE0} %{name} +cp -p %{SOURCE1} . +%patch0 -p0 + + +%build +# Build the SMIUCV helper +gcc $RPM_OPT_FLAGS -o smiucv smiucv.c + + +%install +mkdir -p $RPM_BUILD_ROOT%{_bindir} +install -p -m755 %{name} smiucv ${RPM_BUILD_ROOT}%{_bindir} + + +%files +%{_bindir}/* + + +%changelog +* Wed Aug 12 2015 Rafael Fonseca - 1.1-3 +- Update runtime requirements. +- Fix generation of debuginfo pkg. + +* Wed Aug 12 2015 Rafael Fonseca - 1.1-2 +- Fix installation of smiucv binary +- Fix usage of flags for compilation + +* Tue Aug 11 2015 Rafael Fonseca - 1.1-1 +- Initial package diff --git a/smiucv.c b/smiucv.c new file mode 100644 index 0000000..b3aa40a --- /dev/null +++ b/smiucv.c @@ -0,0 +1,263 @@ +/* +||======================================================================= +|| smiucv - Helper utility that provides an IUCV interface to the z/VM +|| System Management API (SMAPI). +|| +|| This utility reads requests from stdin, sends them to the SMAPI server +|| via IUCV and writes the response to stdout. It's intended for use by +|| the smaclient shell command. +|| +|| Usage: +|| +|| smiucv [user] [name] response +|| +|| User and name are optional and will default to VSMREQIU and DMSRSRQU. +|| +|| Written by Leland Lucius +||======================================================================= +*/ + +#include +#include +#include +#include +#include +#include +#include +#include + +/* +|| Default remote IUCV user and name +*/ +#define IUCV_USER "VSMREQIU" +#define IUCV_NAME "DMSRSRQU" + +/* +|| Read data from the SMAPI server and write it to stdout +*/ +int +readwrite( int fd, void *ptr, int len ) +{ + unsigned char *buffer = (unsigned char *) ptr; + struct timeval timeout; + fd_set readfds; + int i; + int rc; + + /* + || Initialize timeout + */ + timeout.tv_sec = 30; + timeout.tv_usec = 0; + + /* + || Large responses will arrive in chunks + */ + for( i = 0; i < len; i += rc ) + { + /* + || Wait for timeout or data + */ + FD_ZERO( &readfds); + FD_SET( fd, &readfds ); + if( ( rc = select( fd + 1, &readfds, NULL, NULL, &timeout ) ) < 0 ) + { + fprintf( stderr, "select() failed: %d - %s\n", errno, strerror( errno ) ); + return 1; + } + else if( rc == 0 ) + { + fprintf( stderr, "Timeout waiting for response from remote\n" ); + return 1; + } + + /* + || Read it + */ + if( ( rc = recv( fd, &buffer[i], len - i, 0 ) ) < 0 ) + { + fprintf( stderr, "Error reading from socket: %d - %s\n", errno, strerror( errno ) ); + return 1; + } + else if( rc == 0 ) + { + fprintf( stderr, "Connection closed by remote\n" ); + return 1; + } + } + + /* + || Write to stdout + */ + if( write( fileno( stdout ), buffer, len ) != len ) + { + fprintf( stderr, "Error writing to stdout: %d - %s\n", errno, strerror( errno ) ); + return 1; + } + + return 0; +} + +int +main( int argc, char *argv[] ) +{ + struct sockaddr_iucv siu; + unsigned char *buffer = NULL; + char *user; + char *name; + int used = 0; + int bufsize = 0; + int fd = -1; + int rc = 0; + int len; + int reqid; + + /* + || Initialize sockaddr + */ + memset( &siu, 0, sizeof( siu ) ); + siu.siucv_family = AF_IUCV; + memset( &siu.siucv_nodeid, ' ', 8 ); + memset( &siu.siucv_user_id, ' ', 8 ); + memset( &siu.siucv_name, ' ', 8 ); + + /* + || Set userid...default or first command line argument + */ + user = IUCV_USER; + if( argc > 1 && argv[ 1 ] ) + { + user = argv[ 1 ]; + } + len = strlen( user ); + memcpy( &siu.siucv_user_id, user, ( len > 8 ? 8 : len ) ); + + /* + || Set name...default or second command line argument + */ + name = IUCV_NAME; + if( argc > 2 && argv[ 2 ] ) + { + name = argv[ 2 ]; + } + len = strlen( name ); + memcpy( &siu.siucv_name, name, ( len > 8 ? 8 : len ) ); + + /* + || Allocate an IUCV socket + */ + fd = socket( AF_IUCV, SOCK_STREAM, IPPROTO_IP ); + if( fd == -1 ) + { + fprintf( stderr, "Unable to create socket: %d - %s", errno, strerror( errno ) ); + rc = 1; + goto die; + } + + /* + || Bind it + */ + rc = bind( fd, (struct sockaddr *) &siu, sizeof( siu ) ); + if( rc < 0 ) + { + fprintf( stderr, "Unable to bind: %d - %s", errno, strerror( errno ) ); + rc = 1; + goto die; + } + + /* + || Connect to partner + */ + rc = connect( fd, (struct sockaddr *) &siu, sizeof( siu ) ); + if( rc == -1 ) + { + fprintf( stderr, "Unable to connect: %d - %s", errno, strerror( errno ) ); + rc = 1; + goto die; + } + + /* + || Read request into buffer + */ + do + { + if( used == bufsize ) + { + bufsize += 8192; + buffer = realloc( buffer, bufsize ); + if( buffer == NULL ) + { + fprintf( stderr, "Unable to alloc buffer: %d - %s\n", errno, strerror( errno ) ); + rc = 1; + goto die; + } + } + } while( read( fileno( stdin ), &buffer[ used++ ], 1 ) == 1 ); + + /* + || Send it to the server + */ + if( write( fd, buffer, --used ) != used ) + { + fprintf( stderr, "Error writing to socket: %d - %s\n", errno, strerror( errno ) ); + rc = 1; + goto die; + } + + /* + || Get the first request ID + */ + if( ( rc = readwrite( fd, &reqid, sizeof( reqid ) ) ) != 0 ) + { + goto die; + } + + /* + || Get the response length + */ + if( ( rc = readwrite( fd, &len, sizeof( len ) ) ) != 0 ) + { + goto die; + } + + /* + || Free original buffer and allocate a new one + */ + free( buffer ); + buffer = malloc( len ); + if( buffer == NULL ) + { + fprintf( stderr, "Unable to alloc buffer: %d - %s\n", errno, strerror( errno ) ); + rc = 1; + goto die; + } + + /* + || Get the response + */ + if( ( rc = readwrite( fd, buffer, len ) ) != 0 ) + { + goto die; + } + +die: + + /* + || Free the buffer + */ + if( buffer ) + { + free( buffer ); + } + + /* + || Kill the socket + */ + if( fd != -1 ) + { + shutdown( fd, SHUT_RDWR ); + close( fd ); + } + + return rc; +}