コード例 #1
0
def dscb1data_from_dsname_and_volser(dsname,
                                     volser,
                                     debug=False,
                                     svc_args=None,
                                     encoding=None):
    if svc_args is None:
        svc_args = bytearray(5 * 8)
    if encoding is None:
        dsname = codecs.encode("{:44s}".format(dsname), encoding=cp1047_oe)
        volser = codecs.encode("{:6s}".format(volser), encoding=cp1047_oe)
    obtain_search = bytearray_set_address_size(
        bytearray(4 + 4 + 4 + 4 + 44 + 6 + 140), 31)
    struct.pack_into(
        '=IIII' + '44s6s',
        obtain_search,
        0,
        0xC1000000 + 0x801,  # CAMLST_SEARCH + CAMLST_EADSCB_OK
        bytearray_buffer_address(obtain_search) + 4 * 4,
        bytearray_buffer_address(obtain_search) + 4 * 4 + 44,
        bytearray_buffer_address(obtain_search) + 4 * 4 + 44 + 6,
        dsname,
        volser)
    struct.pack_into('QQQQQ', svc_args, 0, 0, 0,
                     bytearray_buffer_address(obtain_search), 27,
                     SYSTEM_CALL__SVC)  # CAMLST OBTAIN
    zos_system_call(svc_args)
    rc = struct.unpack_from('=4xI', svc_args, 0)[0]
    if rc != 0:
        raise OSError("CAMLIST SEARCH returned rc=0x%X" % (rc, ))
    if debug:
        print(
            dump_region(
                bytearray_buffer_address(obtain_search) + 4 * 4 + 44 + 6, 140))
    return (obtain_search, 4 * 4 + 44 + 6)
コード例 #2
0
ファイル: load.py プロジェクト: rharriszzz/zos_python
    def build_a24(self, ddname):
        self.a24 = bytearray_set_address_size(bytearray(a24_size), 24)
        a24 = self.a24
        struct.paueck_into('HHHHHHHHHHHHHHHHH', a24, abend_exit_offset,
                             0x5870, 0x1004, # L   R7,4(,R1)   # R7 is the DCB 
                             0x9104, 0x1003, # TM  3(R1),X'04' # is it ignorable?
                             0x4770, 0xF012, # BNZ *+10
                             0x9200, 0x1003, # MVI 3(R1),X'00' # if we can't ignore, allow it to abend
                             0x07FE,         # BR R14          # return
                             0x9204, 0x1003, # MVI 3(R1),X'04' # ignore it
                             0xA77A, 0xFFFF & -dcb_offset, # AHI R7,xxxx
                             0xD203, 0x7000, 0x1000, # MVC 0(R7),0(R1)
                             0x07FE)         # BR R14          # return

        struct.pack_into('I', a24, exit_list_offset,
                            ((0x80 + 0x11)<<24) + (bytearray_buffer_address(a24) + abend_exit_offset))

        # DCB DSORG=PO,MACRF=R
        for i in (0x17, 0x1F, 0x23, 0x37, 0x3B, 0x47, 0x4B, 0x4F, 0x57):
            a24[dcb_offset + i] = 0x01
        a24[dcb_offset + 0x1A] = 0x02
        a24[dcb_offset + 0x30] = 0x02
        a24[dcb_offset + 0x32] = 0x24
        struct.pack_into("8s", a24, dcb_offset + 0x28,
                            codecs.encode("{:8s}".format(ddname), encoding=cp1047_oe))
        exit_list_address = bytearray(4)
        struct.pack_into('I', exit_list_address, 0,
                         bytearray_buffer_address(a24) + exit_list_offset)
        struct.pack_into("3s", a24, dcb_offset + 0x35,
                         exit_list_address[1:])
コード例 #3
0
 def call(self, request_type, criteria={}, requested_fields=None):
     self.requested_fields = requested_fields
     ssob_and_stat = self.ssob_and_stat
     arglist = self.arglist
     save_area = self.save_area
     ssreq = self.ssreq
     request_types = ('job_terse', 'job_verbose', 'close', 'sysout_terse',
                      'sysout_verbose', 'data_set_list')
     struct.pack_into('B', ssob_and_stat, 0x2C,
                      request_types.index(request_type) + 1)
     for name, value in criteria.items():
         if not value:
             continue
         struct_fmt, position_list, bit_position, bit = criteria_fields[
             name]
         if isinstance(value, str):
             value = codecs.encode(
                 ("{:%ds}" % int(struct_fmt[:-1])).format(value),
                 encoding=cp1047_oe)
         if isinstance(position_list, tuple):
             for position in position_list:
                 struct.pack_into(struct_fmt, ssob_and_stat, position,
                                  value)
         else:
             position = position_list
             struct.pack_into(struct_fmt, ssob_and_stat, position, value)
         ssob_and_stat[bit_position] |= bit
     struct.pack_into('QQQQQ', ssreq, 0, ssreq_fn, 0,
                      bytearray_buffer_address(arglist),
                      bytearray_buffer_address(save_area),
                      SYSTEM_CALL__CALL31)
     zos_system_call(ssreq)
     self.ssi_return_code = struct.unpack_from('=4xI', self.ssreq, 0)[0]
     if self.ssi_return_code != 0:
         error_index = self.ssi_return_code / 4 - 1
         error_messages = (
             "The subsystem does not support this function.",
             "The subsystem exists, but is not active.",
             "The subsystem is not defined to MVS.",
             "Invalid SSOB, SSIB or function code",
             "The SSOB or SSIB have invalid lengths or formats",
             "The SSI has not been initialized.")
         raise Exception(error_messages[errior_index])
     self.subsystem_return_code = struct.unpack_from(
         '=I', ssob_and_stat, 0x0C)[0]  # SSOBRETN
     self.version, self.reason, self.reason2 = struct.unpack_from(
         '=BxBB', self.ssob_and_stat, 0x28)  # STATVER, STATREAS, STATREA2
     if self.ssi_return_code == 4:
         raise Exception("Invalid search arguments")
     elif self.ssi_return_code == 8:
         raise Exception("Logic error, reason=0x%X" % self.reason)
     elif self.ssi_return_code == 12:
         raise Exception("Unsupported call type")
     #print(dump_region(bytearray_buffer_address(ssob_and_stat), len(self.ssob_and_stat)))
     return None
コード例 #4
0
ファイル: ps.py プロジェクト: rharriszzz/zos_python
 def __init__(self, outputs, pid=0, thid=0, asid=0, loginname=None):
     self.pid = pid
     self.thid = thid
     self.pgtha = self.make_pgtha(outputs,
                                  pid=pid,
                                  thid=thid,
                                  asid=asid,
                                  loginname=loginname)
     pgtha = self.pgtha
     self.pgthb = self.make_pgthb()
     pgthb = self.pgthb
     self.BPX1GTH_args = bytearray(7 * 8 + 2 * 8 + 5 * 4)
     BPX1GTH_args = self.BPX1GTH_args
     struct.pack_into(
         'QQQQQQQ'
         'QQ'
         'IIIII', BPX1GTH_args, 0,
         bytearray_buffer_address(BPX1GTH_args) + 9 * 8 + 0 * 4,
         bytearray_buffer_address(BPX1GTH_args) + 7 * 8,
         bytearray_buffer_address(BPX1GTH_args) + 9 * 8 + 1 * 4,
         bytearray_buffer_address(BPX1GTH_args) + 8 * 8,
         bytearray_buffer_address(BPX1GTH_args) + 9 * 8 + 2 * 4,
         bytearray_buffer_address(BPX1GTH_args) + 9 * 8 + 3 * 4,
         bytearray_buffer_address(BPX1GTH_args) + 9 * 8 + 4 * 4,
         bytearray_buffer_address(pgtha), bytearray_buffer_address(pgthb),
         len(pgtha), len(pgthb), 0, 0, 0)
     self.call_args = bytearray(5 * 8)
コード例 #5
0
ファイル: load.py プロジェクト: rharriszzz/zos_python
 def close(self):
     # CLOSE (MYDCB),MODE=31
     a24 = self.a24
     bldl_list = self.bldl_list
     close_args = bytearray_set_address_size(bytearray(8), 31)
     struct.pack_into('=B3xI', close_args, 0,
                         0x80, bytearray_buffer_address(a24) + dcb_offset)
     struct.pack_into('QQQQQ', self.svc_args, 0,
                      0, bytearray_buffer_address(close_args), 0,
                      20, SYSTEM_CALL__SVC) 
     zos_system_call(self.svc_args)
     rc = struct.unpack_from('Q', self.svc_args, 0)
コード例 #6
0
ファイル: load.py プロジェクト: rharriszzz/zos_python
 def load(self):
     # LOAD DE=bldl_list,DCB=dcb,ERRRET=NEXT
     a24 = self.a24
     bldl_list = self.bldl_list
     struct.pack_into('QQQQQ', self.svc_args, 0,
                      0, bytearray_buffer_address(bldl_list)+4, 0x80000000 + (bytearray_buffer_address(a24) + dcb_offset),
                      8, SYSTEM_CALL__SVC) 
     zos_system_call(self.svc_args)
     #unsigned int r15; /* good:0                         bad:returnCode */
     #unsigned int r0;  /* good:ep_including_amode        bad:n/a  */
     #unsigned int r1;  /* good:apf+length_in_doublewords bad:reasonCode */
     codes = struct.unpack_from("4xI8x4xI", self.svc_args, 0) # ignore the high order 32 bits
     if codes[0] == 0:
         self.ep = struct.unpack_from("4xI", self.svc_args, 1*8)[0]
     else:
         raise OSError("LOAD return_code=%X, reason_code=%X" % codes)
コード例 #7
0
def show_text_units(text_unit_array):
    text_unit_array_address = bytearray_buffer_address(text_unit_array)
    end = False
    tu_count = 0
    while not end:
        tu_address = struct.unpack_from("I", text_unit_array, tu_count * 4)[0]
        offset = tu_address - text_unit_array_address
        tu_count += 1
        end = 0 != (offset & 0x80000000)
        offset = offset & 0x7FFFFFFF
        code = struct.unpack_from("H", text_unit_array, offset)[0]
        offset += 2
        count = struct.unpack_from("H", text_unit_array, offset)[0]
        offset += 2
        print("%04X %04X " % (code, count), end=('\n' if count == 0 else ''))
        for index in range(count):
            if index > 0:
                print("          ", end='')
            length = struct.unpack_from("H", text_unit_array, offset)[0]
            offset += 2
            print("%04X " % length, end='')
            data = struct.unpack_from("%ds" % length, text_unit_array,
                                      offset)[0]
            offset += length
            for i in range(len(data)):
                print("%02X" % data[i], end=' ')
            print('')
コード例 #8
0
ファイル: load.py プロジェクト: rharriszzz/zos_python
 def bldl(self, name):
     a24 = self.a24
     # BLDL bldl_list,dcb
     self.bldl_list = bytearray_set_address_size(bytearray(72), 31)
     bldl_list = self.bldl_list
     struct.pack_into('=HH8s', self.bldl_list, 0,
                         1, 68, codecs.encode("{:8s}".format(name), encoding=cp1047_oe) )
     if self.verbose:
         print(["%08X" % v for v in struct.unpack_from('III', self.bldl_list, 0)])
     struct.pack_into('QQQQQ', self.svc_args, 0,
                      0, bytearray_buffer_address(bldl_list), bytearray_buffer_address(a24) + dcb_offset,
                      18, SYSTEM_CALL__SVC) 
     zos_system_call(self.svc_args)
     rc, reason = struct.unpack_from('7xB7xB', self.svc_args, 0)
     if rc > 0:
         raise OSError("BLDL failed for %s, rc=%X, reason=%X" % (self.name, rc, reason))
コード例 #9
0
 def parse_information(self, address, remaining_length, result=None):
     if not result:
         result = {}
     type_and_modifier = ctypes.c_ushort.from_address(address + 0x2).value
     data_format = structure_info.get(type_and_modifier, ())
     if data_format:
         address += 4
         for name, ctype, offset, convert, size in data_format:
             if name and (not self.requested_fields
                          or name in self.requested_fields):
                 if self.verbose:
                     print("%X %s %s" % (offset, name,
                                         dump_region(address + offset,
                                                     size,
                                                     show_header=False,
                                                     show_address=False)),
                           flush=True)
                 if ctype:
                     value = convert(
                         ctype.from_address(address + offset).value)
                 else:
                     value = bytearray(size)
                     ctypes.memmove(bytearray_buffer_address(value),
                                    address + offset, size)
                 if value:
                     result[name] = value
     return result
コード例 #10
0
ファイル: load.py プロジェクト: rharriszzz/zos_python
 def open(self):
     # OPEN (dcb,(INPUT)),MODE=31
     a24 = self.a24
     open_args = bytearray_set_address_size(bytearray(8), 31)
     struct.pack_into('=B3xI', open_args, 0,
                         0x80, bytearray_buffer_address(a24) + dcb_offset)
     struct.pack_into('QQQQQ', self.svc_args, 0,
                      0, bytearray_buffer_address(open_args), 0,
                      19, SYSTEM_CALL__SVC) 
     zos_system_call(self.svc_args)
     rc = struct.unpack_from('7xB', self.svc_args, 0)[0]
     if rc > 4:
         abend_code = struct.unpack_from('I', a24, 0)[0]
         if abend_code:
             raise OSError("OPEN abend %X" % abend_code)
         else:
             raise OSError("OPEN failed, rc=%X" % rc)
コード例 #11
0
def volser_from_dsname(dsname, svc_args=None, encoding=None):
    if svc_args is None:
        svc_args = bytearray(5 * 8)
    if encoding is None:
        dsname = codecs.encode("{:44s}".format(dsname), encoding=cp1047_oe)
    locate = bytearray_set_address_size(
        bytearray(4 + 4 + 4 + 4 + 44 + 4 + 265), 31)
    struct.pack_into('=IIII' + '44s', locate, 0, 0x44000000,
                     bytearray_buffer_address(locate) + 4 * 4, 0,
                     bytearray_buffer_address(locate) + 4 * 4 + 44 + 4, dsname)
    struct.pack_into('QQQQQ', svc_args, 0, 0, 0,
                     bytearray_buffer_address(locate), 26,
                     SYSTEM_CALL__SVC)  # LOCATE
    zos_system_call(svc_args)
    rc = struct.unpack_from('=4xI', svc_args, 0)[0]
    if rc != 0:
        raise OSError("LOCATE NAME returned rc=0x%X" % (rc, ))
    volser = struct.unpack_from('6s', locate, 4 * 4 + 44 + 4 + 2 + 4)[0]
    if encoding is None:
        volser = codecs.decode(volser_ebcdic, cp1047_oe)
    locate = None
    return volser
コード例 #12
0
ファイル: load.py プロジェクト: rharriszzz/zos_python
def load(name):
    name_buffer = bytearray_set_address_size(bytearray(8), 31)
    struct.pack_into("8s", name_buffer, 0, codecs.encode("{:8s}".format(name), encoding=cp1047_oe))
    
    load_params = bytearray_set_address_size(bytearray(3*4), 31)
    struct.pack_into('IIBBBB', load_params, 0,
                     bytearray_buffer_address(name_buffer), 0, 0, 0, 0x20, 0)

    svc_args = bytearray(5*8)
    struct.pack_into('QQQQQ', svc_args, 0,
                     9, 0, bytearray_buffer_address(load_params),
                     122, SYSTEM_CALL__SVC)

    zos_system_call(svc_args)
    
    #unsigned int r15; /* good:0                         bad:returnCode */
    #unsigned int r0;  /* good:ep_including_amode        bad:n/a  */
    #unsigned int r1;  /* good:apf+length_in_doublewords bad:reasonCode */
    codes = struct.unpack_from("4xI8x4xI", svc_args, 0) # ignore the high order 32 bits
    if codes[0] == 0:
        return struct.unpack_from("4xI", svc_args, 1*8)[0]
    else:
        raise OSError("LOAD return_code=%X, reason_code=%X" % codes)
コード例 #13
0
ファイル: ps.py プロジェクト: rharriszzz/zos_python
 def __next__(self):
     BPX1GTH_args = self.BPX1GTH_args
     rc = struct.unpack_from('i', BPX1GTH_args, 9 * 8 + 2 * 4)[0]
     if rc == -1:
         raise StopIteration()
     struct.pack_into('QQQQQ', self.call_args, 0, BPX1GTH_addr, 0,
                      bytearray_buffer_address(BPX1GTH_args), 0,
                      SYSTEM_CALL__CALL)
     zos_system_call(self.call_args)
     rc = struct.unpack_from('I', BPX1GTH_args, 9 * 8 + 2 * 4)[0]
     if rc == -1:
         raise StopIteration()
     self.move_next_from_pgthb_to_pgtha()
     if self.pid and self.pid != self.pgtha_pid:
         raise StopIteration()
     if self.thid and self.thid != self.pgtha_thid:
         raise StopIteration()
     return self.extract_data_from_pgthb()
コード例 #14
0
def allocate_spool_dataset(data_set_name=None,
                           client_token=None,
                           subsystem=None):
    bytearray_set_address_size(client_token, 31)
    rc, results = dynalloc({
        "DSNAME":
        data_set_name,
        "STATUS":
        "SHR",
        "UNAUTHORIZED_SUBSYSTER_REQUEST":
        subsystem,
        "BROWSE_TOKEN":
        (codecs.encode("BTKN", encoding=cp1047_oe), bytes(
            (3, 3)), bytearray_buffer_address(client_token).to_bytes(
                4, sys.byteorder) if client_token else 0, 0, 0, 0, 0),
        "CLOSE":
        None,
        "DDNAME_RETURN":
        None
    })
    if rc != 0:
        raise OSError("dynalloc returned %X" % rc)
    return results["DDNAME_RETURN"]
コード例 #15
0
def dynallocInternal(verb,
                     text_unit_mapping,
                     flags1=0,
                     flags2=0,
                     verbose=False,
                     message_level=0,
                     message_function=print_message):
    keyword_definitions = text_keyword_definitions[verb]
    text_unit_array_size = process_text_units(text_unit_mapping,
                                              keyword_definitions,
                                              None,
                                              verbose=verbose)
    if verbose:
        print("test_unit_array_size = %r" % text_unit_array_size)
    text_unit_array = bytearray_set_address_size(
        bytearray(text_unit_array_size), 31)
    process_text_units(text_unit_mapping,
                       keyword_definitions,
                       text_unit_array,
                       verbose=verbose)
    if verbose:
        show_text_units(text_unit_array)

    message_severity_level = 0  # informational, that is, include all the messages
    message_block_subpool = 4
    message_options = 0x48  # return message to caller + specified subpool

    svc99rbx = bytearray_set_address_size(bytearray(36), 31)
    struct.pack_into(
        'BBBBBBBBBBB',
        svc99rbx,
        0,
        0xE2,
        0xF9,
        0xF9,
        0xD9,
        0xC2,
        0xE7,
        1,  #'S99RBX', version
        message_options,
        message_block_subpool,
        8,
        message_severity_level)

    svc99rb = bytearray_set_address_size(bytearray(20), 31)
    struct.pack_into('BBHHHIII', svc99rb, 0, 20, verb_codes[verb], flags1, 0,
                     0, bytearray_buffer_address(text_unit_array),
                     bytearray_buffer_address(svc99rbx), flags2)

    svc99plist = bytearray_set_address_size(bytearray(4), 31)
    struct.pack_into('I', svc99plist, 0,
                     0x80000000 | bytearray_buffer_address(svc99rb))

    svc_args = bytearray(5 * 8)
    struct.pack_into('QQQQQ', svc_args, 0, 0, 0,
                     bytearray_buffer_address(svc99plist), 99,
                     SYSTEM_CALL__SVC)

    zos_system_call(svc_args)
    svc99_rc = struct.unpack_from('L', svc_args, 0)[0]

    if verbose:
        s99error_and_info = struct.unpack_from('HH', svc99rb, 4)
        print("s99rc=%X, error=%04X, info=%04X" %
              (svc99_rc, s99error_and_info[0], s99error_and_info[1]))
        show_text_units(text_unit_array)
    retrieve_dynalloc_messages(message_function,
                               verb,
                               keyword_definitions,
                               svc99rbx,
                               svc99rb,
                               svc_args,
                               verbose=verbose)

    output_mapping = process_text_units(text_unit_mapping,
                                        keyword_definitions,
                                        text_unit_array,
                                        tu_input=False,
                                        verbose=verbose)
    return (svc99_rc, output_mapping)
コード例 #16
0
def retrieve_dynalloc_messages(message_function,
                               verbName,
                               keyword_definitions,
                               svc99rbx,
                               svc99rb,
                               svc_args,
                               verbose=False):
    svc99_rc = struct.unpack_from('L', svc_args, 0)[0]
    s99error = struct.unpack_from('H', svc99rb, 4)[0]
    s99info = struct.unpack_from('H', svc99rb, 6)[0]
    if svc99_rc != 0:
        message_function("%s failed, return code=%d, error=%04X, info=%04X" %
                         (verbName, svc99_rc, s99error, s99info))
    block_count = svc99rbx[11]
    if verbose:
        print("s99rbx message_count = %d" % block_count)
    if block_count == 0:
        return
    if block_count > MAX_EM_MESSAGES:
        block_count = MAX_EM_MESSAGES

    emMessages = bytearray_set_address_size(bytearray(256 * block_count), 31)

    emCall = bytearray_set_address_size(bytearray(28), 31)
    struct.pack_into('BBBxII4xI', emCall, 0, 0x20, 50, block_count,
                     bytearray_buffer_address(svc99rb), svc99_rc,
                     bytearray_buffer_address(emMessages))
    if verbose:
        print(["%08X" % v for v in struct.unpack_from('IIIII', emCall, 0)])

    emCallPlist = bytearray_set_address_size(bytearray(4), 31)
    struct.pack_into('I', emCallPlist, 0,
                     0x80000000 | bytearray_buffer_address(emCall))

    save_area = bytearray_set_address_size(bytearray(18 * 4), 31)

    call_args = bytearray(5 * 8)
    struct.pack_into('QQQQQ', call_args, 0, get_IEFDB476(), 0,
                     bytearray_buffer_address(emCallPlist),
                     bytearray_buffer_address(save_area), SYSTEM_CALL__CALL31)

    zos_system_call(call_args)
    IEFDB476_rc = struct.unpack_from('Q', call_args, 0)[0]
    if verbose:
        print("IEFDB476_rc=%X" % IEFDB476_rc)

    if verbose:
        print(
            ["%X" % v for v in struct.unpack_from('xxBBIIHHI', svc99rbx, 16)])
        print(["%X" % v for v in struct.unpack_from('BBBxII4xI', emCall, 0)])
        print("block_count=%X" % block_count)
    for i in range(block_count):
        message_length = struct.unpack_from('H', emMessages, 256 * i)[0]
        if verbose:
            print('message_length=%d' % message_length)
        message_text = emMessages[256 * i + 4:256 * i + 4 + message_length]
        message = str.rstrip(codecs.decode(message_text, cp1047_oe))
        message_function(message)

    if s99error == 0x035C:  # Invalid PARM specified in text unit, with corresponding message IKJ56231I
        info = keyword_definitions[s99info]
        if info:
            message_function("text unit %04X is %s %s" %
                             (s99info, info[0][0], info[0][2]))
コード例 #17
0
def process_text_units(text_unit_mapping,
                       keyword_definitions,
                       text_unit_array,
                       tu_input=True,
                       verbose=False):
    if text_unit_array:
        text_unit_array_address = bytearray_buffer_address(text_unit_array)
    return_mapping = {} if not tu_input else None
    tu_count = len(text_unit_mapping.items())
    ptr_offset = 0
    size = tu_count * 4
    count = 0
    for key, value in text_unit_mapping.items():
        count += 1
        definition = keyword_definitions[key]
        if verbose:
            print(definition)
        tu_type = definition[KEYWORD_DEFINITION_TYPE]
        max_len = definition[KEYWORD_DEFINITION_MAX_LEN]
        max_value_count = definition[KEYWORD_DEFINITION_MAX_COUNT]
        code = definition[KEYWORD_DEFINITION_KEY]
        return_value = definition[KEYWORD_DEFINITION_RETURN] if len(
            definition) >= (KEYWORD_DEFINITION_RETURN + 1) else None
        if not tu_input and not return_value:
            continue
        if text_unit_array:
            tu_offset = (count - 1) * 4
            if tu_input:
                struct.pack_into(
                    "I", text_unit_array, tu_offset, text_unit_array_address +
                    size + (0 if count < tu_count else 1 << 31))
                struct.pack_into("H", text_unit_array, size, code)
            else:
                size = (struct.unpack_from("I", text_unit_array, tu_offset)[0]
                        & 0x7FFFFFFF) - text_unit_array_address
        size += 2
        if (code == DALSYSOU and value == '*') or (
                code == DALSSNM and value is None) or max_value_count == 0:
            value = ()
            min_value_count = 0
        else:
            min_value_count = 1
        if tu_input:
            if return_value:
                value_count = max_value_count
            else:
                if isinstance(
                        value,
                        str) or not isinstance(value, collections.Iterable):
                    value = (value, )
                value_count = len(value)
                if value_count > max_value_count or value_count < min_value_count:
                    raise ValueError
            if text_unit_array:
                struct.pack_into("H", text_unit_array, size, value_count)
        else:
            value = []
            value_count = struct.unpack_from("H", text_unit_array, size)[0]
        size += 2
        for element in value if not return_value else range(value_count):
            if return_value:
                if tu_input:
                    if text_unit_array:
                        struct.pack_into("H", text_unit_array, size, max_len)
                    size += 2 + max_len
                else:
                    len_element = struct.unpack_from("H", text_unit_array,
                                                     size)[0]
                    size += 2
                    if tu_type == KD_TYPE_VARCHAR:
                        element = str.rstrip(
                            codecs.decode(
                                struct.unpack_from("%ds" % len_element,
                                                   text_unit_array, size)[0],
                                cp1047_oe))
                    else:
                        offset = 0
                        if len_element == 1:
                            fmt = 'B'
                        elif len_element == 2:
                            fmt = 'H'
                        elif len_element == 3:
                            fmt = 'I'
                        else:
                            fmt = 'I'
                        element = struct.unpack_from(fmt, text_unit_array,
                                                     size + offset)[0]
                        if len_element == 3:
                            element = element & 0xFFFFFF
                        if isinstance(tu_type, collections.Mapping):
                            pass  # FIXME. invert the mapping and use it to decode the value
                    value.append(element)
                continue
            if isinstance(element, str):
                if isinstance(tu_type, collections.Mapping):
                    element = tu_type[element]
                else:
                    element = codecs.encode(element, encoding=cp1047_oe)
            if isinstance(element, int):
                if text_unit_array and tu_input:
                    struct.pack_into("H", text_unit_array, size, max_len)
                size += 2
                nb = max_len
                while nb > 0:
                    if text_unit_array and tu_input:
                        text_unit_array[size + nb - 1] = element & 0xFF
                    element = element >> 8
                    nb -= 1
                size += max_len
                continue
            len_element = len(element)
            if text_unit_array and tu_input:
                struct.pack_into("H", text_unit_array, size, len_element)
            size += 2
            if text_unit_array and tu_input:
                struct.pack_into("%ds" % len_element, text_unit_array, size,
                                 element)
            size += len_element
        if not tu_input:
            if max_value_count == 1:
                value = value[0]
            return_mapping[definition[KEYWORD_DEFINITION_NAMES][0]] = value
    return size if tu_input else return_mapping
コード例 #18
0
class extended_status:
    verbose = False
    ssreq_fn = MEM4(MEM4(MEM4(0, 0x10), 0x128), 0x14)
    ssob_and_stat_len = 0x23C  # version 10
    ssob_and_stat = bytearray_set_address_size(bytearray(ssob_and_stat_len),
                                               31)
    arglist = bytearray_set_address_size(bytearray(4), 31)
    struct.pack_into('=I', arglist, 0, bytearray_buffer_address(ssob_and_stat))
    struct.pack_into(
        '=4sHHI4xI',
        ssob_and_stat,
        0,
        codecs.encode("{:4s}".format("SSOB"), encoding=cp1047_oe),  # E2E2D6C2
        0x1C,
        80,
        0,
        bytearray_buffer_address(ssob_and_stat) +
        0x20)  # 0x1C is the SSOB length; 80 is extended status
    struct.pack_into(
        'H4sBB5x',
        ssob_and_stat,
        0x20,
        0x21C,  # version 10 length
        codecs.encode("{:4s}".format("STAT"), encoding=cp1047_oe),  # E2E3C1E3
        10,
        0)  # version 10, modifier 0
    struct.pack_into(
        'B',
        ssob_and_stat,
        0xDA,  # STATOPT1
        0x04)  # Returned areas may be obtained in 64-bit storage
    save_area = bytearray_set_address_size(bytearray(18 * 4), 31)
    ssreq = bytearray(5 * 8)

    def call(self, request_type, criteria={}, requested_fields=None):
        self.requested_fields = requested_fields
        ssob_and_stat = self.ssob_and_stat
        arglist = self.arglist
        save_area = self.save_area
        ssreq = self.ssreq
        request_types = ('job_terse', 'job_verbose', 'close', 'sysout_terse',
                         'sysout_verbose', 'data_set_list')
        struct.pack_into('B', ssob_and_stat, 0x2C,
                         request_types.index(request_type) + 1)
        for name, value in criteria.items():
            if not value:
                continue
            struct_fmt, position_list, bit_position, bit = criteria_fields[
                name]
            if isinstance(value, str):
                value = codecs.encode(
                    ("{:%ds}" % int(struct_fmt[:-1])).format(value),
                    encoding=cp1047_oe)
            if isinstance(position_list, tuple):
                for position in position_list:
                    struct.pack_into(struct_fmt, ssob_and_stat, position,
                                     value)
            else:
                position = position_list
                struct.pack_into(struct_fmt, ssob_and_stat, position, value)
            ssob_and_stat[bit_position] |= bit
        struct.pack_into('QQQQQ', ssreq, 0, ssreq_fn, 0,
                         bytearray_buffer_address(arglist),
                         bytearray_buffer_address(save_area),
                         SYSTEM_CALL__CALL31)
        zos_system_call(ssreq)
        self.ssi_return_code = struct.unpack_from('=4xI', self.ssreq, 0)[0]
        if self.ssi_return_code != 0:
            error_index = self.ssi_return_code / 4 - 1
            error_messages = (
                "The subsystem does not support this function.",
                "The subsystem exists, but is not active.",
                "The subsystem is not defined to MVS.",
                "Invalid SSOB, SSIB or function code",
                "The SSOB or SSIB have invalid lengths or formats",
                "The SSI has not been initialized.")
            raise Exception(error_messages[errior_index])
        self.subsystem_return_code = struct.unpack_from(
            '=I', ssob_and_stat, 0x0C)[0]  # SSOBRETN
        self.version, self.reason, self.reason2 = struct.unpack_from(
            '=BxBB', self.ssob_and_stat, 0x28)  # STATVER, STATREAS, STATREA2
        if self.ssi_return_code == 4:
            raise Exception("Invalid search arguments")
        elif self.ssi_return_code == 8:
            raise Exception("Logic error, reason=0x%X" % self.reason)
        elif self.ssi_return_code == 12:
            raise Exception("Unsupported call type")
        #print(dump_region(bytearray_buffer_address(ssob_and_stat), len(self.ssob_and_stat)))
        return None

    def job_elements(self):
        have_64bit_results = struct.unpack_from('B', self.ssob_and_stat,
                                                0x108)[0] & 0x40
        for self.jq64 in (True, False) if have_64bit_results else (False, ):
            self.jqe_address = struct.unpack_from(
                'Q' if self.jq64 else 'I', self.ssob_and_stat,
                0x118 if self.jq64 else 0x0F4)[0]
            if self.verbose:
                print("jq64=%r, jqe=%X" % (self.jq64, self.jqe_address))
            while self.jqe_address:
                self.subsystem_name = codecs.decode((ctypes.c_char*4)\
                                                    .from_address(self.jqe_address + 0x10).value, cp1047_oe)
                job = {"subsystem": self.subsystem_name}
                job = self.parse_element_information(self.jqe_address,
                                                     'job_terse', job)
                self.job_verbose_address = (ctypes.c_ulong if self.jq64 else ctypes.c_uint)\
                    .from_address(self.jqe_address + (0x30 if self.jq64 else 0x14)).value
                if self.job_verbose_address:
                    if self.verbose:
                        print("job_verbose=%X" % (self.job_verbose_address, ))
                    job = self.parse_element_information(
                        self.job_verbose_address, 'job_verbose', job)
                yield job
                self.jqe_address = (ctypes.c_ulong if self.jq64 else ctypes.c_uint)\
                    .from_address(self.jqe_address + (0x20 if self.jq64 else 0x08)).value
                if self.verbose:
                    print("jqe=%X" % (self.jqe_address, ))

    def job_dependency_elements(self):
        if ctypes.c_short.from_address(self.jqe_address + 0x4).value >= 0x48:
            self.dependency_address = ctypes.c_ulong.from_address(
                self.jqe_address + 0x40).value
            while self.dependency_address:
                yield self.parse_element_information(self.dependency_address,
                                                     'job_dependency')
                self.dependency_address = ctypes.c_ulong.from_address(
                    self.dependency_address + 0x8).value

    def sysout_terse_elements(self):
        self.sysout_terse_address = (ctypes.c_ulong if self.jq64 else ctypes.c_uint)\
            .from_address(self.jqe_address + (0x28 if self.jq64 else 0x0C)).value
        while self.sysout_terse_address:
            yield self.parse_element_information(self.sysout_terse_address,
                                                 'sysout_terse')
            self.sysout_terse_address = (ctypes.c_ulong if self.jq64 else ctypes.c_uint)\
                .from_address(self.sysout_terse_address + (0x18 if self.jq64 else 0x08)).value

    def sysout_verbose_elements(self):
        self.sysout_verbose_address = (ctypes.c_ulong if self.jq64 else ctypes.c_uint)\
            .from_address(self.sysout_terse_address + (0x28 if self.jq64 else 0x10)).value
        while self.sysout_verbose_address:
            yield self.parse_element_information(self.sysout_verbose_address,
                                                 'sysout_verbose')
            self.sysout_verbose_address = (ctypes.c_ulong if self.jq64 else ctypes.c_uint)\
                .from_address(self.sysout_verbose_address + (0x30 if self.jq64 else 0x14)).value

    def parse_element_information(self,
                                  header_address,
                                  header_type,
                                  result=None):
        if not result:
            result = {}
        offset = ctypes.c_ushort.from_address(header_address + 0x4).value
        total_length = ctypes.c_ushort.from_address(header_address + offset +
                                                    0x0).value
        address = header_address + offset
        offset = 4
        while offset < total_length:
            section_length = ctypes.c_ushort.from_address(address + offset +
                                                          0x0).value
            result = self.parse_information(address + offset,
                                            total_length - offset, result)
            offset += section_length
        return result

    def parse_information(self, address, remaining_length, result=None):
        if not result:
            result = {}
        type_and_modifier = ctypes.c_ushort.from_address(address + 0x2).value
        data_format = structure_info.get(type_and_modifier, ())
        if data_format:
            address += 4
            for name, ctype, offset, convert, size in data_format:
                if name and (not self.requested_fields
                             or name in self.requested_fields):
                    if self.verbose:
                        print("%X %s %s" % (offset, name,
                                            dump_region(address + offset,
                                                        size,
                                                        show_header=False,
                                                        show_address=False)),
                              flush=True)
                    if ctype:
                        value = convert(
                            ctype.from_address(address + offset).value)
                    else:
                        value = bytearray(size)
                        ctypes.memmove(bytearray_buffer_address(value),
                                       address + offset, size)
                    if value:
                        result[name] = value
        return result