├── src
└── PyEterm
│ ├── __init__.py
│ ├── utils.py
│ ├── PyEtermLibrary.py
│ └── matiplib.py
├── .gitignore
├── README.md
├── .settings
└── org.eclipse.core.resources.prefs
├── .project
├── .pydevproject
└── LICENSE
/src/PyEterm/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | /src/config.cgi
2 | /scr/*.pyc
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | pyeterm
2 | =======
3 |
4 | python实现eterm接口
5 |
--------------------------------------------------------------------------------
/.settings/org.eclipse.core.resources.prefs:
--------------------------------------------------------------------------------
1 | eclipse.preferences.version=1
2 | encoding//src/PyEterm/PyEtermLibrary.py=utf-8
3 | encoding//src/PyEterm/matiplib.py=utf-8
4 | encoding//src/PyEterm/utils.py=utf-8
5 |
--------------------------------------------------------------------------------
/.project:
--------------------------------------------------------------------------------
1 |
2 |
3 | pyeterm
4 |
5 |
6 |
7 |
8 |
9 | org.python.pydev.PyDevBuilder
10 |
11 |
12 |
13 |
14 |
15 | org.python.pydev.pythonNature
16 |
17 |
18 |
--------------------------------------------------------------------------------
/.pydevproject:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | /${PROJECT_DIR_NAME}/src
5 |
6 | python 2.7
7 | Default
8 |
9 |
--------------------------------------------------------------------------------
/src/PyEterm/utils.py:
--------------------------------------------------------------------------------
1 | # -*- coding:utf-8 -*-
2 | '''
3 | Created on Oct 16, 2014
4 |
5 | @author: czl
6 | '''
7 | import re
8 |
9 | def AscToHex(buf):
10 | strs = re.findall(r'\w{2}', buf)
11 | return ''.join(chr(int(strs)))
12 |
13 | def hex_format(text):
14 | return [('%02x' % (ord(ch))) for ch in text]
15 |
16 | def asc_format(text):
17 | res = []
18 | for ch in text:
19 | if ch >=' ' and ch <= '~' :
20 | res.append(' %c' % ch)
21 | else:
22 | res.append(' .')
23 | return res
24 |
25 | def hex_print(text, colNumPerLine=16):
26 | hexText = hex_format(text)
27 | ascText = asc_format(text)
28 | assert(len(hexText) == len(ascText))
29 | res = []
30 | for index in range(0, len(hexText), colNumPerLine):
31 | res.append(' '.join(hexText[index:index+colNumPerLine]))
32 | res.append(' '.join(ascText[index:index+colNumPerLine]))
33 | print '\n'.join(res)
34 |
35 | if __name__ == '__main__':
36 | pass
37 |
--------------------------------------------------------------------------------
/src/PyEterm/PyEtermLibrary.py:
--------------------------------------------------------------------------------
1 | # -*- coding:utf-8 -*-
2 | '''
3 | Created on Oct 16, 2014
4 |
5 | @author: czl
6 | '''
7 |
8 | from PyEterm.utils import hex_print
9 | import uuid
10 | import ConfigParser
11 | import codecs
12 | import os
13 | from PyEterm.matiplib import MATIP
14 | import re
15 | import logging
16 |
17 | class PyEtermLibrary(object):
18 | '''
19 | classdocs
20 | '''
21 |
22 | ver = 1
23 | debug_level = 0
24 | eterm_print_pattern = re.compile(r"([^\r]{80})")
25 |
26 | def __init__(self):
27 | '''
28 | Constructor
29 | '''
30 | self.matip = MATIP()
31 | self.ascus = []
32 | self.currentSessionIndex = 0
33 |
34 | def connect(self, host, port):
35 | if not isinstance(port, int):
36 | port = int(port)
37 | self.matip.connect(host, port)
38 | return "connect success"
39 |
40 | def __getMac(self):
41 | node = uuid.getnode()
42 | mac = uuid.UUID(int=node)
43 | return mac.hex[-12:]
44 |
45 | def login(self, username, password):
46 | if isinstance(username, unicode):
47 | username = username.encode("ascii", "ignore")
48 | if isinstance(password, unicode):
49 | password = password.encode("ascii", "ignore")
50 |
51 | ## 构造登录报文
52 | content = chr(self.ver) # version
53 | content += chr(0xa2) # 内容长度162个字节
54 |
55 | assert(len(username) <= 16)
56 | assert(len(password) <= 32)
57 | content += username.ljust(16, chr(0))
58 | content += password.ljust(32, chr(0))
59 |
60 | mac = self.__getMac()
61 | content += mac.ljust(12, chr(0))
62 | localip = self.matip.sock.getsockname()[0]
63 | content += localip.ljust(16, chr(0x20))
64 | content += "3832010.000000" #the magic code
65 | content = content.ljust(162, chr(0))
66 |
67 | ## 登录并记录session id
68 |
69 | h1s = []
70 | while 1:
71 | self.matip.send(content)
72 | resp = self.matip.getreply()
73 | if ord(resp[0]) == 0 and ord(resp[1]) == len(resp) and ord(resp[2]) == 1:
74 | self.sessionCount = ord(resp[4])
75 | for i in range(self.sessionCount):
76 | ind = 5 + 5 * i
77 | self.ascus.append(resp[ind:ind + 5]) # save the H1 H2 A1 A2
78 | if resp[ind] != chr(0):
79 | h1s.append(resp[ind])
80 | break
81 | else:
82 | logging.error("login error")
83 |
84 | ## ascus open
85 | content = self.matip.getSessionOpenPacket(cd=4, styp=1, mpx=0, hdr=0, pres=2, h1=0, h2=0)
86 | self.matip.send(content)
87 | resp = self.matip.getreply()
88 |
89 | content = ''
90 | # for h1 in (chr(0x0c), chr(0x29), chr(0x20)):
91 | for h1 in h1s:
92 | content += self.matip.getSessionOpenPacket(cd=4, styp=1, mpx=0, hdr=0, pres=2, h1=ord(h1), h2=0)
93 | self.matip.send(content)
94 | resp = self.matip.getreply()
95 | resp = self.matip.getreply()
96 | return "login success"
97 |
98 | def changeToSession(self, index):
99 | if not isinstance(index, int):
100 | index = int(index)
101 | self.currentSessionIndex = index - 1
102 |
103 | def eterm_print(self, cmd, text):
104 | beginIndex = text.find("\x1b\x4d") + 2
105 | endIndex = text.rfind("\x1e\x1b\x62")
106 | content = ">" + cmd + "\r" + text[beginIndex:endIndex] + ">"
107 | content = self.eterm_print_pattern.sub(r"\1\r", content)
108 | content = content.replace('\x0d', os.linesep)
109 | print content
110 | return content
111 |
112 | def sendCmd(self, cmd):
113 | data = "\x02\x1b\x0b\x20\x20\x00\x0f\x1e"
114 | data += cmd.strip()
115 | data += "\x20"
116 | content = self.matip.getDataPacket(self.ascus[self.currentSessionIndex], data)
117 |
118 | if self.debug_level > 0:
119 | hex_print(content)
120 | self.matip.send(content)
121 |
122 | resp = self.matip.getreply()
123 | return self.eterm_print(cmd, resp)
124 |
125 | if __name__ == "__main__":
126 | logging.basicConfig(level=logging.DEBUG)
127 | logging.info("hello")
128 |
129 | config = ConfigParser.ConfigParser()
130 | config.readfp(codecs.open('../config.cgi', 'r', 'utf-8-sig'))
131 |
132 | server = config.get("eterm", "server")
133 | port = config.getint("eterm", "port")
134 | username = config.get("eterm", "username")
135 | password = config.get("eterm", "password")
136 |
137 | el = PyEtermLibrary()
138 | el.connect(server, port)
139 | el.login(username, password)
140 | resp = el.sendCmd("da")
141 | resp = el.sendCmd("av:canpek/30oct/cz")
142 | # el.sendCmd("IHD:CA")
143 |
144 |
145 |
146 |
147 |
--------------------------------------------------------------------------------
/src/PyEterm/matiplib.py:
--------------------------------------------------------------------------------
1 | # -*- coding:utf-8 -*-
2 | '''
3 | Created on Oct 16, 2014
4 |
5 | @author: czl
6 | '''
7 |
8 | import socket
9 | from sys import stderr
10 | import struct
11 |
12 |
13 | MATIP_PORT = 350
14 |
15 | class MATIPException(Exception):
16 | '''
17 | Base class for all exceptions raised by this module.
18 | '''
19 |
20 |
21 | class MATIPServerDisconnected(MATIPException):
22 | '''Not connected to any MATIP server.
23 |
24 | This exception is raised when the server unexpectedly disconnects,
25 | or when an attempt is made to use the SMTP instance before
26 | connecting it to a server.
27 | '''
28 |
29 | class MATIPResponseException(MATIPException):
30 | """Base class for all exceptions that include an MATIP error code.
31 | """
32 |
33 | class MATIP(object):
34 | '''
35 | classdocs
36 | '''
37 |
38 | debuglevel = 0
39 | file = None
40 | default_port = 350
41 |
42 | ver = 1
43 |
44 | def __init__(self, host='', port=0,
45 | timeout=socket._GLOBAL_DEFAULT_TIMEOUT):
46 | '''
47 | Constructor
48 | '''
49 | self.timeout = timeout
50 | if host:
51 | self.connect(host, port)
52 |
53 |
54 | def set_debuglevel(self, debuglevel):
55 | self.debuglevel = debuglevel
56 |
57 | def _get_socket(self, host, port, timeout):
58 | if self.debuglevel > 0:
59 | print>>stderr, 'create connect:', (host, port)
60 | return socket.create_connection((host, port), timeout)
61 |
62 | def connect(self, host='localhost', port=0):
63 | if not port and (host.find(':') == host.rfind(':')):
64 | i = host.rfind(':')
65 | if i >= 0:
66 | host, port = host[:i], host[i+1:]
67 | try:
68 | port = int(port)
69 | except ValueError:
70 | raise socket.error, "nonnumeric port"
71 | if not port:
72 | port = self.default_port
73 | if self.debuglevel > 0:
74 | print>>stderr, 'connect:', (host, port)
75 | self.sock = self._get_socket(host, port, self.timeout)
76 |
77 | def send(self, content):
78 | if self.debuglevel > 0:
79 | print>>stderr, 'send;', repr(content)
80 | if hasattr(self, 'sock') and self.sock:
81 | try:
82 | self.sock.sendall(content)
83 | except socket.error:
84 | self.close()
85 | raise MATIPServerDisconnected('Server not connected')
86 | else:
87 | raise MATIPServerDisconnected('Please run connect() first')
88 |
89 | def getreply(self):
90 | # if self.file is None:
91 | # self.file = self.sock.makefile('rb')
92 | try:
93 | # resp = self.file.readline()
94 | resp = self.sock.recv(4096)
95 | except socket.error as e:
96 | self.close()
97 | raise MATIPServerDisconnected("Connection unexpectedly closed: "
98 | + str(e))
99 | if resp == '':
100 | self.close()
101 | raise MATIPServerDisconnected("Connection unexpectedly closed")
102 | if self.debuglevel > 0:
103 | print>>stderr, 'reply:', repr(resp)
104 | return resp
105 |
106 |
107 | def createPacket(self, version, cmd, content):
108 | msg = chr(version)
109 | msg += chr(cmd)
110 | msg += struct.pack("!H", len(content)+4)
111 | msg += content
112 | return msg
113 |
114 | def getSessionOpenPacket(self, cd, styp, mpx, hdr, pres, h1, h2, ascus=[]):
115 | '''
116 | get the session open message
117 |
118 | 0 1 2 3
119 | 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
120 | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
121 | |0|0|0|0|0| Ver |1|1 1 1 1 1 1 0| length |
122 | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
123 | |0 0|0 1|0| CD | STYP |0 0 0 0| RFU |MPX|HDR| PRES. |
124 | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
125 | | H1 | H2 | RFU |
126 | |-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
127 | | Reserved | RFU | Nbr of ASCUs |
128 | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
129 | | Nbr of ASCUs | ASCU list (opt) |
130 | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
131 |
132 | CD
133 | This field specifies the Coding
134 | 000 : 5 bits (padded baudot)
135 | 010 : 6 bits (IPARS)
136 | 100 : 7 bits (ASCII)
137 | 110 : 8 bits (EBCDIC)
138 | xx1 : R.F.U
139 |
140 | STYP
141 | This is the traffic subtype (type being TYPE A).
142 | 0001 : TYPE A Conversational
143 |
144 | MPX
145 | This flag specifies the multiplexing used within the TCP session.
146 | Possible values are:
147 | 00 : Group of ASCU with 4 bytes identification per ASCU (H1H2A1A2)
148 | 01 : Group of ASCUs with 2 bytes identification per ASCU (A1A2)
149 | 10 : single ASCU inside the TCP session.
150 |
151 | HDR
152 | This field specifies which part of the airline’s specific address is
153 | placed ahead of the message texts transmitted over the session.
154 | Possible values are:
155 | 00 : ASCU header = H1+H2+A1+A2
156 | 01 : ASCU Header = A1+A2
157 | 10 : No Header
158 | 11 : Not used
159 | The MPX and HDR must be coherent. When ASCUs are multiplexed, the data
160 | must contain the ASCU identification. The table below summarizes the
161 | allowed combinations:
162 | +-----------------------+
163 | | MPX | 00 | 01 | 10 |
164 | +-----------------------+
165 | | HDR | |
166 | | 00 | Y | Y | Y |
167 | | 01 | N | Y | Y |
168 | | 10 | N | N | Y |
169 | +-----------------------+
170 |
171 | PRES
172 | This field indicates the presentation format
173 | 0001 : P1024B presentation
174 | 0010 : P1024C presentation
175 | 0011 : 3270 presentation
176 |
177 | H1 H2
178 | These fields can logically identify the session if MPX is not equal to
179 | 00. When this field is not used, it must be set to 0. If used in
180 | session (MPX <> 0) with HDR=00, H1H2 in data packet must have the same
181 | value as set in SO command.
182 |
183 | Nbr of ASCUs
184 | Nbr_of_ASCUs field is mandatory and gives the number of ASCUs per
185 | session. A 0 (zero) value means unknown. In this case the ASCU list is
186 | not present in the ‘Open Session’ command and must be sent by the
187 | other end in the ‘Open Confirm’ command.
188 |
189 | ASCU LIST
190 | Contains the list of identifier for each ASCU. If MPX=00 it has a
191 | length of four bytes (H1H2A1A2) for each ASCU, otherwise it is two
192 | bytes (A1A2).
193 | '''
194 | content = chr(1<<4 | cd)
195 | content += chr(styp<<4)
196 | content += chr(0) # RFU
197 | content += chr(mpx<<6 | hdr<<4 | pres)
198 | content += chr(h1)
199 | content += chr(h2)
200 | content += ''.ljust(2, chr(0)) # RFU
201 | content += chr(0) # Reserved
202 | content += ''.ljust(2, chr(0)) # RFU
203 | content += struct.pack("!H", len(ascus))
204 |
205 | if mpx == 0:
206 | fmt = "4B" # 4个字节(H1H2A1A2)
207 | else:
208 | fmt = "2B" # 2个字节(A1A2)
209 | for ascu in ascus:
210 | content += struct.pack(fmt, *ascu)
211 |
212 | return self.createPacket(self.ver, 0xFE, content)
213 |
214 | def getDataPacket(self, ascu, data):
215 | content = ascu[:3]+chr(1)+ascu[3:]
216 | content += chr(0x70)
217 | content += data
218 | content += chr(0x3)
219 | return self.createPacket(self.ver, 0, content)
220 |
221 | def close(self):
222 | if self.file:
223 | self.file.close()
224 | self.file = None
225 | if self.sock:
226 | self.sock.close()
227 | self.sock = None
228 |
229 |
230 | if __name__ == "__main__":
231 | import ConfigParser
232 | import codecs
233 | config = ConfigParser.ConfigParser()
234 | config.readfp(codecs.open('config.cgi', 'r', 'utf-8-sig'))
235 |
236 | server = config.get("eterm", "server")
237 | port = config.getint("eterm", "port")
238 | username = config.get("eterm", "username")
239 | password = config.get("eterm", "password")
240 |
241 | el = MATIP()
242 | el.set_debuglevel(1)
243 | el.connect(server, port)
244 |
245 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Eclipse Public License - v 1.0
2 |
3 | THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS ECLIPSE PUBLIC
4 | LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THE PROGRAM
5 | CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT.
6 |
7 | 1. DEFINITIONS
8 |
9 | "Contribution" means:
10 |
11 | a) in the case of the initial Contributor, the initial code and documentation
12 | distributed under this Agreement, and
13 | b) in the case of each subsequent Contributor:
14 | i) changes to the Program, and
15 | ii) additions to the Program;
16 |
17 | where such changes and/or additions to the Program originate from and are
18 | distributed by that particular Contributor. A Contribution 'originates'
19 | from a Contributor if it was added to the Program by such Contributor
20 | itself or anyone acting on such Contributor's behalf. Contributions do not
21 | include additions to the Program which: (i) are separate modules of
22 | software distributed in conjunction with the Program under their own
23 | license agreement, and (ii) are not derivative works of the Program.
24 |
25 | "Contributor" means any person or entity that distributes the Program.
26 |
27 | "Licensed Patents" mean patent claims licensable by a Contributor which are
28 | necessarily infringed by the use or sale of its Contribution alone or when
29 | combined with the Program.
30 |
31 | "Program" means the Contributions distributed in accordance with this
32 | Agreement.
33 |
34 | "Recipient" means anyone who receives the Program under this Agreement,
35 | including all Contributors.
36 |
37 | 2. GRANT OF RIGHTS
38 | a) Subject to the terms of this Agreement, each Contributor hereby grants
39 | Recipient a non-exclusive, worldwide, royalty-free copyright license to
40 | reproduce, prepare derivative works of, publicly display, publicly
41 | perform, distribute and sublicense the Contribution of such Contributor,
42 | if any, and such derivative works, in source code and object code form.
43 | b) Subject to the terms of this Agreement, each Contributor hereby grants
44 | Recipient a non-exclusive, worldwide, royalty-free patent license under
45 | Licensed Patents to make, use, sell, offer to sell, import and otherwise
46 | transfer the Contribution of such Contributor, if any, in source code and
47 | object code form. This patent license shall apply to the combination of
48 | the Contribution and the Program if, at the time the Contribution is
49 | added by the Contributor, such addition of the Contribution causes such
50 | combination to be covered by the Licensed Patents. The patent license
51 | shall not apply to any other combinations which include the Contribution.
52 | No hardware per se is licensed hereunder.
53 | c) Recipient understands that although each Contributor grants the licenses
54 | to its Contributions set forth herein, no assurances are provided by any
55 | Contributor that the Program does not infringe the patent or other
56 | intellectual property rights of any other entity. Each Contributor
57 | disclaims any liability to Recipient for claims brought by any other
58 | entity based on infringement of intellectual property rights or
59 | otherwise. As a condition to exercising the rights and licenses granted
60 | hereunder, each Recipient hereby assumes sole responsibility to secure
61 | any other intellectual property rights needed, if any. For example, if a
62 | third party patent license is required to allow Recipient to distribute
63 | the Program, it is Recipient's responsibility to acquire that license
64 | before distributing the Program.
65 | d) Each Contributor represents that to its knowledge it has sufficient
66 | copyright rights in its Contribution, if any, to grant the copyright
67 | license set forth in this Agreement.
68 |
69 | 3. REQUIREMENTS
70 |
71 | A Contributor may choose to distribute the Program in object code form under
72 | its own license agreement, provided that:
73 |
74 | a) it complies with the terms and conditions of this Agreement; and
75 | b) its license agreement:
76 | i) effectively disclaims on behalf of all Contributors all warranties
77 | and conditions, express and implied, including warranties or
78 | conditions of title and non-infringement, and implied warranties or
79 | conditions of merchantability and fitness for a particular purpose;
80 | ii) effectively excludes on behalf of all Contributors all liability for
81 | damages, including direct, indirect, special, incidental and
82 | consequential damages, such as lost profits;
83 | iii) states that any provisions which differ from this Agreement are
84 | offered by that Contributor alone and not by any other party; and
85 | iv) states that source code for the Program is available from such
86 | Contributor, and informs licensees how to obtain it in a reasonable
87 | manner on or through a medium customarily used for software exchange.
88 |
89 | When the Program is made available in source code form:
90 |
91 | a) it must be made available under this Agreement; and
92 | b) a copy of this Agreement must be included with each copy of the Program.
93 | Contributors may not remove or alter any copyright notices contained
94 | within the Program.
95 |
96 | Each Contributor must identify itself as the originator of its Contribution,
97 | if
98 | any, in a manner that reasonably allows subsequent Recipients to identify the
99 | originator of the Contribution.
100 |
101 | 4. COMMERCIAL DISTRIBUTION
102 |
103 | Commercial distributors of software may accept certain responsibilities with
104 | respect to end users, business partners and the like. While this license is
105 | intended to facilitate the commercial use of the Program, the Contributor who
106 | includes the Program in a commercial product offering should do so in a manner
107 | which does not create potential liability for other Contributors. Therefore,
108 | if a Contributor includes the Program in a commercial product offering, such
109 | Contributor ("Commercial Contributor") hereby agrees to defend and indemnify
110 | every other Contributor ("Indemnified Contributor") against any losses,
111 | damages and costs (collectively "Losses") arising from claims, lawsuits and
112 | other legal actions brought by a third party against the Indemnified
113 | Contributor to the extent caused by the acts or omissions of such Commercial
114 | Contributor in connection with its distribution of the Program in a commercial
115 | product offering. The obligations in this section do not apply to any claims
116 | or Losses relating to any actual or alleged intellectual property
117 | infringement. In order to qualify, an Indemnified Contributor must:
118 | a) promptly notify the Commercial Contributor in writing of such claim, and
119 | b) allow the Commercial Contributor to control, and cooperate with the
120 | Commercial Contributor in, the defense and any related settlement
121 | negotiations. The Indemnified Contributor may participate in any such claim at
122 | its own expense.
123 |
124 | For example, a Contributor might include the Program in a commercial product
125 | offering, Product X. That Contributor is then a Commercial Contributor. If
126 | that Commercial Contributor then makes performance claims, or offers
127 | warranties related to Product X, those performance claims and warranties are
128 | such Commercial Contributor's responsibility alone. Under this section, the
129 | Commercial Contributor would have to defend claims against the other
130 | Contributors related to those performance claims and warranties, and if a
131 | court requires any other Contributor to pay any damages as a result, the
132 | Commercial Contributor must pay those damages.
133 |
134 | 5. NO WARRANTY
135 |
136 | EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS PROVIDED ON AN
137 | "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR
138 | IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE,
139 | NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each
140 | Recipient is solely responsible for determining the appropriateness of using
141 | and distributing the Program and assumes all risks associated with its
142 | exercise of rights under this Agreement , including but not limited to the
143 | risks and costs of program errors, compliance with applicable laws, damage to
144 | or loss of data, programs or equipment, and unavailability or interruption of
145 | operations.
146 |
147 | 6. DISCLAIMER OF LIABILITY
148 |
149 | EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR ANY
150 | CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL,
151 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION
152 | LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
153 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
154 | ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE
155 | EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY
156 | OF SUCH DAMAGES.
157 |
158 | 7. GENERAL
159 |
160 | If any provision of this Agreement is invalid or unenforceable under
161 | applicable law, it shall not affect the validity or enforceability of the
162 | remainder of the terms of this Agreement, and without further action by the
163 | parties hereto, such provision shall be reformed to the minimum extent
164 | necessary to make such provision valid and enforceable.
165 |
166 | If Recipient institutes patent litigation against any entity (including a
167 | cross-claim or counterclaim in a lawsuit) alleging that the Program itself
168 | (excluding combinations of the Program with other software or hardware)
169 | infringes such Recipient's patent(s), then such Recipient's rights granted
170 | under Section 2(b) shall terminate as of the date such litigation is filed.
171 |
172 | All Recipient's rights under this Agreement shall terminate if it fails to
173 | comply with any of the material terms or conditions of this Agreement and does
174 | not cure such failure in a reasonable period of time after becoming aware of
175 | such noncompliance. If all Recipient's rights under this Agreement terminate,
176 | Recipient agrees to cease use and distribution of the Program as soon as
177 | reasonably practicable. However, Recipient's obligations under this Agreement
178 | and any licenses granted by Recipient relating to the Program shall continue
179 | and survive.
180 |
181 | Everyone is permitted to copy and distribute copies of this Agreement, but in
182 | order to avoid inconsistency the Agreement is copyrighted and may only be
183 | modified in the following manner. The Agreement Steward reserves the right to
184 | publish new versions (including revisions) of this Agreement from time to
185 | time. No one other than the Agreement Steward has the right to modify this
186 | Agreement. The Eclipse Foundation is the initial Agreement Steward. The
187 | Eclipse Foundation may assign the responsibility to serve as the Agreement
188 | Steward to a suitable separate entity. Each new version of the Agreement will
189 | be given a distinguishing version number. The Program (including
190 | Contributions) may always be distributed subject to the version of the
191 | Agreement under which it was received. In addition, after a new version of the
192 | Agreement is published, Contributor may elect to distribute the Program
193 | (including its Contributions) under the new version. Except as expressly
194 | stated in Sections 2(a) and 2(b) above, Recipient receives no rights or
195 | licenses to the intellectual property of any Contributor under this Agreement,
196 | whether expressly, by implication, estoppel or otherwise. All rights in the
197 | Program not expressly granted under this Agreement are reserved.
198 |
199 | This Agreement is governed by the laws of the State of New York and the
200 | intellectual property laws of the United States of America. No party to this
201 | Agreement will bring a legal action under this Agreement more than one year
202 | after the cause of action arose. Each party waives its rights to a jury trial in
203 | any resulting litigation.
204 |
205 |
--------------------------------------------------------------------------------