This file is indexed.

/usr/share/pyshared/hl7/client.py is in python-hl7 0.2.2-1.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
from optparse import OptionParser

import os.path
import socket
import sys


SB = '\x0b' #<SB>, vertical tab
EB = '\x1c' #<EB>, file separator
CR = '\x0d' #<CR>, \r

FF = '\x0c' # <FF>, new page form feed

RECV_BUFFER = 4096

class MLLPException(Exception): pass

class MLLPClient(object):
    """
    A basic, blocking, HL7 MLLP client based upon :py:mod:`socket`.

    MLLPClient implements two methods for sending data to the server.

    * :py:meth:`MLLPClient.send` for raw data that already is wrapped in the
      appropriate MLLP container (e.g. *<SB>message<EB><CR>*).
    * :py:meth:`MLLPClient.send_message` will wrap the message in the MLLP
      container

    Can be used by the ``with`` statement to ensure :py:meth:`MLLPClient.close`
    is called::

        with MLLPClient(host, port) as client:
            client.send_message('MSH|...')

    """
    def __init__(self, host, port):
        self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        self.socket.connect((host, port))

    def __enter__(self):
        return self

    def __exit__(self, exc_type, exc_val, trackeback):
        self.close()

    def close(self):
        """Release the socket connection"""
        self.socket.close()

    def send_message(self, message):
        """Wraps a str, unicode, or :py:cls:`hl7.Message` in a MLLP container
        and send the message to the server
        """
        # wrap in MLLP message container
        data = SB + unicode(message) + EB + CR
        # TODO consider encoding (e.g. UTF-8)
        return self.send(data)

    def send(self, data):
        """Low-level, direct access to the socket.send (data must be already
        wrapped in an MLLP container).  Blocks until the server returns.
        """
        # upload the data
        self.socket.send(data)
        # wait for the ACK/NACK
        return self.socket.recv(RECV_BUFFER)


# wrappers to make testing easier
def stdout(content):
    sys.stdout.write(content + '\n')

def stdin():
    return sys.stdin

def stderr():
    return sys.stderr

def read_stream(stream):
    """Buffer the stream and yield individual, stripped messages"""
    _buffer = ''

    while True:
        data = stream.read(RECV_BUFFER)
        if data == '':
            break
        # usually should be broken up by EB, but I have seen FF separating
        # messages
        messages = (_buffer + data).split(EB if FF not in data else FF)

        # whatever is in the last chunk is an uncompleted message, so put back
        # into the buffer
        _buffer = messages.pop(-1)

        for m in messages:
            yield m.strip(SB+CR)

    if len(_buffer.strip()) > 0:
        raise MLLPException('buffer not terminated: %s' % _buffer)

def read_loose(stream):
    """Turn a single HL7-like blob of text into a real HL7 message"""
    # load all the data (should only be 1 message)
    data = stream.read()

    # Windows new lines to segment separators
    data = data.replace('\r\n', '\r')

    # take out all the the typical MLLP separators and trailing
    # whitespace
    data = data.strip(EB+FF+SB+CR+'\n ')

    yield data

def mllp_send():
    """Command line tool to send messages to an MLLP server"""
    # set up the command line options
    script_name = os.path.basename(sys.argv[0])
    parser = OptionParser(usage=script_name + ' [options] <server>')
    parser.add_option('-p', '--port',
                  action='store', type='int', dest='port', default=6661,
                  help='port to connect to')
    parser.add_option('-f', '--file', dest='filename',
                  help='read from FILE instead of stdin', metavar='FILE')
    parser.add_option('-q', '--quiet',
                  action='store_true', dest='verbose', default=True,
                  help='do not print status messages to stdout')
    parser.add_option('--loose',
                  action='store_true', dest='loose', default=False,
                  help='allow file to be a HL7-like object (\\r\\n ' \
                      + 'instead of \\r). Can ONLY send 1 message. Requires ' \
                      + '--file option (no stdin)')

    (options, args) = parser.parse_args()
    if len(args) == 1:
        host = args[0]
    else:
        # server not present
        parser.print_usage()
        stderr().write('server required\n')
        return

    if options.filename is not None:
        stream = open(options.filename, 'rb') #FIXME with_statement
    else:
        if options.loose:
            stderr().write('--loose requires --file with a single message\n')
            return
        stream = stdin()

    with MLLPClient(host, options.port) as client:
        message_stream = read_stream(stream) \
                         if not options.loose \
                         else read_loose(stream)

        for message in message_stream:
            result = client.send_message(message)
            if options.verbose:
                stdout(result)


if __name__ == '__main__':
    mllp_send()