Contribution- persistent connection code for Mail::Transport::SMTP

Eugene L Schulman <[email protected]> Fri, 3 Jun 2005 18:50:08 -0400
Newsgroups gmane.comp.lang.perl.modules.mail-box
Message-ID <OF66E611AD.2F4A6EBD-ON85257015.00771B92-85257015.007D7113@us.ibm.com>
--=_mixed 007D6ED285257015_=
Content-Type: multipart/alternative; boundary="=_alternative 007D6ED585257015_="


--=_alternative 007D6ED585257015_=
Content-Type: text/plain; charset="US-ASCII"

Mr. Overmeer and team,
        I'm using Mail-Box v2.060 (as published on CPAN) for a critical 
business project for one of my clients.  I have to say the workmanship is 
fantastic, and the asset reuse is commendable.  I'm using it as a part of 
a small middleware integration program that converts a series of 
specialized XML messages into SMTP, and reliably delivers each message. 
The current release of a specific E-mail connector my company provides 
does not attempt the functional breadth I needed- there were some special 
requirements in this project.

I'm writing about the Mail::Transport::SMTP class.  I needed it to perform 
at a higher rate for my application.  The bottleneck for this application 
was the fact that the v2.060 class limited itself to transmitting one 
message over a connection.  Each message sent required a new connection, 
and establishing the new connection was too slow.

In the following contribution, I took a stab at a variation that 
implements connection persistence.

Inside, you'll find new functions:
        contactAnyServer_persist()
        trySend_persist()
        DESTROY()
        ... and a new hash item in the class object init() called 
'connx_persist', which is a hash of { hostname => ref to Net::SMTP }.

I added a trivial advisory lock in case someone wants to use it in a 
multithreaded application.
I admit it can probably be written a lot better.



Example calling (snippet):
use POSIX; use Sys::Hostname;
use Mail::Transport::Send; use Mail::Transport::SMTP;
use Mail::Message;
# @messages is an array of existing refs to Mail::Message objects;

MAILOUT: {
 my $sender = Mail::Transport::SMTP->new(
        'hostname' => "$SMTP_MX",
        'smtp_debug' => 1,
        'retry' => 0);

 ## ATTEMPT FIRST MESSAGE
 foreach my $message (@messages)
 {
        my @RETURN_CODE=$sender->trySend_persist($message);
 
        if ($RETURN_CODE[0]) # SUCCESS
        {
                print STDERR "SUCCESS !!\n";
        }
        else
        {
                print "trySend(): ".join(" ",@RETURN_CODE)."\n";
                exit EXIT_FAILURE;
        }
 }
}
exit EXIT_SUCCESS;



I hope this is useful to the Mail-Box user community and the continued 
development of the package.

                Respectfully Yours,
                Gene Schulman

---

Eugene L. Schulman
Senior Consultant and Technical Architect
IBM Global Services
 

--=_alternative 007D6ED585257015_=
Content-Type: text/html; charset="US-ASCII"


<br><font size=2 face="sans-serif">Mr. Overmeer and team,</font>
<br><font size=2 face="sans-serif">&nbsp; &nbsp; &nbsp; &nbsp; I'm
using Mail-Box v2.060 (as published on CPAN) for a critical business project
for one of my clients. &nbsp;I have to say the workmanship is fantastic,
and the asset reuse is commendable. &nbsp;I'm using it as a part of a small
middleware integration program that converts a series of specialized XML
messages into SMTP, and reliably delivers each message. &nbsp; The current
release of a specific E-mail connector my company provides does not attempt
the functional breadth I needed- there were some special requirements in
this project.</font>
<br>
<br><font size=2 face="sans-serif">I'm writing about the Mail::Transport::SMTP
class. &nbsp;I needed it to perform at a higher rate for my application.
&nbsp;The bottleneck for this application was the fact that the v2.060
class limited itself to transmitting one message over a connection. &nbsp;Each
message sent required a new connection, and establishing the new connection
was too slow.</font>
<br>
<br><font size=2 face="sans-serif">In the following contribution, I took
a stab at a variation that implements connection persistence.</font>
<br>
<br><font size=2 face="sans-serif">Inside, you'll find new functions:</font>
<br><font size=2 face="sans-serif">&nbsp; &nbsp; &nbsp; &nbsp; contactAnyServer_persist()</font>
<br><font size=2 face="sans-serif">&nbsp; &nbsp; &nbsp; &nbsp; trySend_persist()</font>
<br><font size=2 face="sans-serif">&nbsp; &nbsp; &nbsp; &nbsp; DESTROY()</font>
<br><font size=2 face="sans-serif">&nbsp; &nbsp; &nbsp; &nbsp; ...
and a new hash item in the class object init() called 'connx_persist',
which is a hash of { hostname =&gt; ref to Net::SMTP }.</font>
<br>
<br><font size=2 face="sans-serif">I added a trivial advisory lock in case
someone wants to use it in a multithreaded application.</font>
<br><font size=2 face="sans-serif">I admit it can probably be written a
lot better.</font>
<br>
<br>
<br>
<br><font size=2 face="sans-serif">Example calling (snippet):</font>
<br><font size=1 face="Courier New">use POSIX; use Sys::Hostname;</font>
<br><font size=1 face="Courier New">use Mail::Transport::Send; use Mail::Transport::SMTP;</font>
<br><font size=1 face="Courier New">use Mail::Message;</font>
<br><font size=1 face="Courier New"># @messages is an array of existing
refs to Mail::Message objects;</font>
<br>
<br><font size=1 face="Courier New">MAILOUT: {</font>
<br><font size=1 face="Courier New">&nbsp;my $sender = Mail::Transport::SMTP-&gt;new(</font>
<br><font size=1 face="Courier New">&nbsp; &nbsp; &nbsp; &nbsp; 'hostname'
=&gt; &quot;$SMTP_MX&quot;,</font>
<br><font size=1 face="Courier New">&nbsp; &nbsp; &nbsp; &nbsp; 'smtp_debug'
=&gt; 1,</font>
<br><font size=1 face="Courier New">&nbsp; &nbsp; &nbsp; &nbsp; 'retry'
=&gt; 0);</font>
<br>
<br><font size=1 face="Courier New">&nbsp;## ATTEMPT FIRST MESSAGE</font>
<br><font size=1 face="Courier New">&nbsp;foreach my $message (@messages)</font>
<br><font size=1 face="Courier New">&nbsp;{</font>
<br><font size=1 face="Courier New">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;my
@RETURN_CODE=$sender-&gt;trySend_persist($message);</font>
<br><font size=1 face="Courier New">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;</font>
<br><font size=1 face="Courier New">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;if
($RETURN_CODE[0]) # SUCCESS</font>
<br><font size=1 face="Courier New">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;{</font>
<br><font size=1 face="Courier New">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp;print STDERR &quot;SUCCESS !!\n&quot;;</font>
<br><font size=1 face="Courier New">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;}</font>
<br><font size=1 face="Courier New">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;else</font>
<br><font size=1 face="Courier New">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;{</font>
<br><font size=1 face="Courier New">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp;print &quot;trySend(): &quot;.join(&quot;
&quot;,@RETURN_CODE).&quot;\n&quot;;</font>
<br><font size=1 face="Courier New">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp;exit EXIT_FAILURE;</font>
<br><font size=1 face="Courier New">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;}</font>
<br><font size=1 face="Courier New">&nbsp;}</font>
<br><font size=1 face="Courier New">}</font>
<br><font size=1 face="Courier New">exit EXIT_SUCCESS;</font>
<br>
<br>
<br>
<br><font size=2 face="sans-serif">I hope this is useful to the Mail-Box
user community and the continued development of the package.</font>
<br>
<br><font size=2 face="sans-serif">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; Respectfully Yours,</font>
<br><font size=2 face="sans-serif">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; Gene Schulman</font>
<br>
<br><font size=2 face="sans-serif">---</font>
<br><font size=2 face="sans-serif"><br>
</font><font size=2 color=blue face="Arial">Eugene L. Schulman</font>
<br><font size=1 color=blue>Senior Consultant and Technical Architect</font>
<br><font size=1 color=blue>IBM Global Services</font>
<br><font size=3>&nbsp;</font>
<br>
--=_alternative 007D6ED585257015_=--
--=_mixed 007D6ED285257015_=
Content-Type: application/octet-stream; name="SMTP.pm"
Content-Disposition: attachment; filename="SMTP.pm"
Content-Transfer-Encoding: base64

dXNlIHN0cmljdDsNCnVzZSB3YXJuaW5nczsNCg0KcGFja2FnZSBNYWlsOjpUcmFuc3BvcnQ6OlNN
VFA7DQp1c2UgdmFycyAnJFZFUlNJT04nOw0KJFZFUlNJT04gPSAnMi4wNjAnOw0KdXNlIGJhc2Ug
J01haWw6OlRyYW5zcG9ydDo6U2VuZCc7DQoNCnVzZSBOZXQ6OlNNVFA7DQoNCiMgRUxTIDIwMDUt
SnVuLTAyDQojIEhhc2ggZm9yIHBlcnNpc3RlbnQgU01UUCBjb25uZWN0aW9ucw0KIyBJbiB0aGlz
IGltcGxlbWVudGF0aW9uLCB0aGUgaGFzaCB3aWxsIGNvbnNpc3Qgb2YgcGFpcnMgb2YgaG9zdG5h
bWUgYW5kIE5ldDo6U01UUCByZWZlcmVuY2UuDQojIFRoZSBjb25zdW1lcnMgb2YgdGhpcyB2YXJp
YWJsZSBhcmUgdHJ5U2VuZF9wZXJzaXN0KCkgYW5kIGNvbnRhY3RBbnlTZXJ2ZXJfcGVyc2lzdCgp
DQoNCg0Kc3ViIGluaXQoJCkNCnsgICBteSAoJHNlbGYsICRhcmdzKSA9IEBfOw0KDQoJJHNlbGYt
PnsnY29ubnhfcGVyc2lzdCd9PXt9ICNFTFMNCgkgdW5sZXNzIChleGlzdHMoJHNlbGYtPnsnY29u
bnhfcGVyc2lzdCd9KSk7DQoNCiAgICBteSAkaG9zdHMgICA9ICRhcmdzLT57aG9zdG5hbWV9Ow0K
ICAgIHVubGVzcygkaG9zdHMpDQogICAgeyAgIHJlcXVpcmUgTmV0OjpDb25maWc7DQogICAgICAg
ICRob3N0cyAgPSAkTmV0OjpDb25maWc6Ok5ldENvbmZpZ3tzbXRwX2hvc3RzfTsNCiAgICAgICAg
dW5kZWYgJGhvc3RzIHVubGVzcyBAJGhvc3RzOw0KICAgICAgICAkYXJncy0+e2hvc3RuYW1lfSA9
ICRob3N0czsNCiAgICB9DQoNCiAgICAkYXJncy0+e3ZpYX0gIHx8PSAnc210cCc7DQogICAgJGFy
Z3MtPntwb3J0fSB8fD0gJzI1JzsNCg0KICAgICRzZWxmLT5TVVBFUjo6aW5pdCgkYXJncykgb3Ig
cmV0dXJuOw0KDQogICAgbXkgJGhlbG8gPSAkYXJncy0+e2hlbG99DQogICAgICB8fCBldmFsIHsg
cmVxdWlyZSBOZXQ6OkNvbmZpZzsgJE5ldDo6Q29uZmlnOjppbmV0X2RvbWFpbiB9DQogICAgICB8
fCBldmFsIHsgcmVxdWlyZSBOZXQ6OkRvbWFpbjsgTmV0OjpEb21haW46Omhvc3RmcWRuKCkgfTsN
Cg0KICAgICRzZWxmLT57TVRTX25ldF9zbXRwX29wdHN9DQogICAgICAgPSB7IEhlbGxvICAgPT4g
JGhlbG8NCiAgICAgICAgICwgRGVidWcgICA9PiAoJGFyZ3MtPntzbXRwX2RlYnVnfSB8fCAwKQ0K
ICAgICAgICAgfTsNCg0Kd2FybiAiRUxTOiBVc2luZyBkb2N0b3JlZCBNYWlsOjpUcmFuc3BvcnQ6
OlNNVFAiOw0KICAgICRzZWxmOw0KfQ0KDQojLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t
LS0tLS0tLS0tLS0tDQoNCg0Kc3ViIHRyeVNlbmQoJEApDQp7ICAgbXkgKCRzZWxmLCAkbWVzc2Fn
ZSwgJWFyZ3MpID0gQF87DQoNCiAgICAjIEZyb20gd2hvbSBpcyB0aGlzIG1lc3NhZ2UuDQogICAg
bXkgJGZyb20gPSAkYXJnc3tmcm9tfSB8fCAkbWVzc2FnZS0+c2VuZGVyIHx8ICc8Pic7DQogICAg
JGZyb20gPSAkZnJvbS0+YWRkcmVzcyBpZiByZWYgJGZyb20gJiYgJGZyb20tPmlzYSgnTWFpbDo6
QWRkcmVzcycpOw0KDQogICAgIyBXaG8gYXJlIHRoZSBkZXN0aW5hdGlvbnMuDQogICAgaWYoZGVm
aW5lZCAkYXJnc3tUb30pDQogICAgeyAgICRzZWxmLT5sb2coV0FSTklORyA9Pg0KICAgIlVzZSBv
cHRpb24gYHRvJyB0byBvdmVycnVsZSB0aGUgZGVzdGluYXRpb246IGBUbycgd291bGQgcmVmZXIg
dG8gYSBmaWVsZCIpOw0KICAgIH0NCg0KICAgIG15IEB0byA9IG1hcCB7JF8tPmFkZHJlc3N9ICRz
ZWxmLT5kZXN0aW5hdGlvbnMoJG1lc3NhZ2UsICRhcmdze3RvfSk7DQoNCiAgICB1bmxlc3MoQHRv
KQ0KICAgIHsgICAkc2VsZi0+bG9nKE5PVElDRSA9Pg0KICAgICAgICAgICAgJ05vIGFkZHJlc3Nl
cyBmb3VuZCB0byBzZW5kIHRoZSBtZXNzYWdlIHRvLCBubyBjb25uZWN0aW9uIG1hZGUnKTsNCiAg
ICAgICAgcmV0dXJuIDE7DQogICAgfQ0KDQogICAgIyBQcmVwYXJlIHRoZSBoZWFkZXINCiAgICBt
eSBAaGVhZGVyOw0KICAgIHJlcXVpcmUgSU86OkxpbmVzOw0KICAgIG15ICRsaW5lcyA9IElPOjpM
aW5lcy0+bmV3KFxAaGVhZGVyKTsNCiAgICAkbWVzc2FnZS0+aGVhZC0+cHJpbnRVbmRpc2Nsb3Nl
ZCgkbGluZXMpOw0KDQogICAgIw0KICAgICMgU2VuZA0KICAgICMNCg0KICAgIGlmKHdhbnRhcnJh
eSkNCiAgICB7ICAgIyBJbiBMSVNUIGNvbnRleHQNCiAgICAgICAgbXkgJHNlcnZlcjsNCiAgICAg
ICAgcmV0dXJuICgwLCA1MDAsICJDb25uZWN0aW9uIEZhaWxlZCIsICJDT05ORUNUIiwgMCkNCiAg
ICAgICAgICAgIHVubGVzcyAkc2VydmVyID0gJHNlbGYtPmNvbnRhY3RBbnlTZXJ2ZXI7DQoNCiAg
ICAgICAgcmV0dXJuICgwLCAkc2VydmVyLT5jb2RlLCAkc2VydmVyLT5tZXNzYWdlLCAnRlJPTScs
ICRzZXJ2ZXItPnF1aXQpDQogICAgICAgICAgICB1bmxlc3MgJHNlcnZlci0+bWFpbCgkZnJvbSk7
DQoNCiAgICAgICAgZm9yZWFjaCAoQHRvKQ0KICAgICAgICB7ICAgICBuZXh0IGlmICRzZXJ2ZXIt
PnRvKCRfKTsNCiMgbXVzdCB3ZSBiZSBhYmxlIHRvIGRpc2FibGUgdGhpcz8NCiMgbmV4dCBpZiAk
YXJnc3tpZ25vcmVfZXJyb25lb3VzX2Rlc3RpbmF0aW9uc30NCiAgICAgICAgICAgICAgcmV0dXJu
ICgwLCAkc2VydmVyLT5jb2RlLCAkc2VydmVyLT5tZXNzYWdlLCJUbyAkXyIsJHNlcnZlci0+cXVp
dCk7DQogICAgICAgIH0NCg0KICAgICAgICAkc2VydmVyLT5kYXRhOw0KICAgICAgICAkc2VydmVy
LT5kYXRhc2VuZCgkXykgZm9yZWFjaCBAaGVhZGVyOw0KICAgICAgICBteSAkYm9keWRhdGEgPSAk
bWVzc2FnZS0+Ym9keS0+ZmlsZTsNCg0KICAgICAgICBpZihyZWYgJGJvZHlkYXRhIGVxICdHTE9C
JykgeyAkc2VydmVyLT5kYXRhc2VuZCgkXykgd2hpbGUgPCRib2R5ZGF0YT4gfQ0KICAgICAgICBl
bHNlICAgIHsgd2hpbGUobXkgJGwgPSAkYm9keWRhdGEtPmdldGxpbmUpIHsgJHNlcnZlci0+ZGF0
YXNlbmQoJGwpIH0gfQ0KDQogICAgICAgIHJldHVybiAoMCwgJHNlcnZlci0+Y29kZSwgJHNlcnZl
ci0+bWVzc2FnZSwgJ0RBVEEnLCAkc2VydmVyLT5xdWl0KQ0KICAgICAgICAgICAgdW5sZXNzICRz
ZXJ2ZXItPmRhdGFlbmQ7DQoNCiAgICAgICAgcmV0dXJuICgkc2VydmVyLT5xdWl0LCAkc2VydmVy
LT5jb2RlLCAkc2VydmVyLT5tZXNzYWdlLCAnUVVJVCcsDQogICAgICAgICAgICAgICAgJHNlcnZl
ci0+Y29kZSk7DQogICAgfQ0KDQogICAgIyBpbiBTQ0FMQVIgY29udGV4dA0KICAgIG15ICRzZXJ2
ZXI7DQogICAgcmV0dXJuIDAgdW5sZXNzICRzZXJ2ZXIgPSAkc2VsZi0+Y29udGFjdEFueVNlcnZl
cjsNCg0KICAgICRzZXJ2ZXItPnF1aXQsIHJldHVybiAwDQogICAgICAgIHVubGVzcyAkc2VydmVy
LT5tYWlsKCRmcm9tKTsNCg0KICAgIGZvcmVhY2ggKEB0bykNCiAgICB7DQogICAgICAgICAgbmV4
dCBpZiAkc2VydmVyLT50bygkXyk7DQojIG11c3Qgd2UgYmUgYWJsZSB0byBkaXNhYmxlIHRoaXM/
DQojIG5leHQgaWYgJGFyZ3N7aWdub3JlX2Vycm9uZW91c19kZXN0aW5hdGlvbnN9DQogICAgICAg
ICAgJHNlcnZlci0+cXVpdDsNCiAgICAgICAgICByZXR1cm4gMDsNCiAgICB9DQoNCiAgICAkc2Vy
dmVyLT5kYXRhOw0KICAgICRzZXJ2ZXItPmRhdGFzZW5kKCRfKSBmb3JlYWNoIEBoZWFkZXI7DQog
ICAgbXkgJGJvZHlkYXRhID0gJG1lc3NhZ2UtPmJvZHktPmZpbGU7DQoNCiAgICBpZihyZWYgJGJv
ZHlkYXRhIGVxICdHTE9CJykgeyAkc2VydmVyLT5kYXRhc2VuZCgkXykgd2hpbGUgPCRib2R5ZGF0
YT4gfQ0KICAgIGVsc2UgICAgeyB3aGlsZShteSAkbCA9ICRib2R5ZGF0YS0+Z2V0bGluZSkgeyAk
c2VydmVyLT5kYXRhc2VuZCgkbCkgfSB9DQoNCiAgICAkc2VydmVyLT5xdWl0LCByZXR1cm4gMA0K
ICAgICAgICB1bmxlc3MgJHNlcnZlci0+ZGF0YWVuZDsNCg0KICAgICRzZXJ2ZXItPnF1aXQ7DQp9
DQoNCiMtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0NCg0KDQpzdWIg
dHJ5U2VuZF9wZXJzaXN0KCRAKQ0KeyAgIG15ICgkc2VsZiwgJG1lc3NhZ2UsICVhcmdzKSA9IEBf
Ow0KDQoNCiAgICAjIEZyb20gd2hvbSBpcyB0aGlzIG1lc3NhZ2UuDQogICAgbXkgJGZyb20gPSAk
YXJnc3tmcm9tfSB8fCAkbWVzc2FnZS0+c2VuZGVyIHx8ICc8Pic7DQogICAgJGZyb20gPSAkZnJv
bS0+YWRkcmVzcyBpZiByZWYgJGZyb20gJiYgJGZyb20tPmlzYSgnTWFpbDo6QWRkcmVzcycpOw0K
DQogICAgIyBXaG8gYXJlIHRoZSBkZXN0aW5hdGlvbnMuDQogICAgaWYoZGVmaW5lZCAkYXJnc3tU
b30pDQogICAgeyAgICRzZWxmLT5sb2coV0FSTklORyA9Pg0KICAgIlVzZSBvcHRpb24gYHRvJyB0
byBvdmVycnVsZSB0aGUgZGVzdGluYXRpb246IGBUbycgd291bGQgcmVmZXIgdG8gYSBmaWVsZCIp
Ow0KICAgIH0NCg0KICAgIG15IEB0byA9IG1hcCB7JF8tPmFkZHJlc3N9ICRzZWxmLT5kZXN0aW5h
dGlvbnMoJG1lc3NhZ2UsICRhcmdze3RvfSk7DQoNCiAgICB1bmxlc3MoQHRvKQ0KICAgIHsgICAk
c2VsZi0+bG9nKE5PVElDRSA9Pg0KICAgICAgICAgICAgJ05vIGFkZHJlc3NlcyBmb3VuZCB0byBz
ZW5kIHRoZSBtZXNzYWdlIHRvLCBubyBjb25uZWN0aW9uIG1hZGUnKTsNCiAgICAgICAgcmV0dXJu
IDE7DQogICAgfQ0KDQogICAgIyBQcmVwYXJlIHRoZSBoZWFkZXINCiAgICBteSBAaGVhZGVyOw0K
ICAgIHJlcXVpcmUgSU86OkxpbmVzOw0KICAgIG15ICRsaW5lcyA9IElPOjpMaW5lcy0+bmV3KFxA
aGVhZGVyKTsNCiAgICAkbWVzc2FnZS0+aGVhZC0+cHJpbnRVbmRpc2Nsb3NlZCgkbGluZXMpOw0K
DQogICAgIw0KICAgICMgU2VuZA0KICAgICMNCg0KCW15ICgkc2VydmVyLCRjaG9zZW5ob3N0KT0k
c2VsZi0+Y29udGFjdEFueVNlcnZlcl9wZXJzaXN0Ow0KDQoJIyBFTFM6IElmIHRoZSBwcm9jZXNz
IHVzaW5nIHRoZSBsaWJyYXJ5IGlzIHRocmVhZGVkLCBtYWtlIHN1cmUgdGhhdCB0aGVyZQ0KCSMg
IGlzIGFuIGFkdmlzb3J5IGxvY2sgb24gdGhlIHJlZmVyZW5jZSB0byB0aGUgTmV0OjpTTVRQIGNv
bm5lY3Rpb24gb2JqZWN0Lg0KCSMgIFRoYXQgd2F5LCBvbmx5IG9uZSB0aHJlYWQgd3JpdGVzIGEg
dHJhbnNhY3Rpb24gdG8gdGhpcyBwYXJ0aWN1bGFyIGNvbm5lY3Rpb24NCgkjICBhdCBvbmUgdGlt
ZS4gIFRoaXMgZG9lcyBub3QgcHJlY2x1ZGUgdGhlIHVzZSBvZiBvdGhlciBjb25uZWN0aW9ucy4N
Cglsb2NrICRzZWxmLT57J2Nvbm54X3BlcnNpc3QnfS0+eyRjaG9zZW5ob3N0fSBpZiAkc2VydmVy
Ow0KDQogICAgaWYod2FudGFycmF5KQ0KICAgIHsgICAjIEluIExJU1QgY29udGV4dA0KDQoJdW5s
ZXNzKCRzZXJ2ZXIpDQoJew0KICAgICAgICAJcmV0dXJuICgwLCA1MDAsICJDb25uZWN0aW9uIEZh
aWxlZCIsICJDT05ORUNUIiwgMCkNCgl9DQoJdW5sZXNzKCRzZXJ2ZXItPm1haWwoJGZyb20pKQ0K
CXsNCgkJbXkgQHJldHZhbD0oMCwgJHNlcnZlci0+Y29kZSwgJHNlcnZlci0+bWVzc2FnZSwgJ0ZS
T00nLCAkc2VydmVyLT5xdWl0KTsNCgkJZGVsZXRlICRzZWxmLT57J2Nvbm54X3BlcnNpc3QnfS0+
eyRjaG9zZW5ob3N0fTsNCgkgICAgICAgIHJldHVybiBAcmV0dmFsOw0KCX0NCg0KICAgICAgICBm
b3JlYWNoIChAdG8pDQogICAgICAgIHsgICAgIG5leHQgaWYgJHNlcnZlci0+dG8oJF8pOw0KIyBt
dXN0IHdlIGJlIGFibGUgdG8gZGlzYWJsZSB0aGlzPw0KIyBuZXh0IGlmICRhcmdze2lnbm9yZV9l
cnJvbmVvdXNfZGVzdGluYXRpb25zfQ0KCQlteSBAcmV0dmFsPSgwLCAkc2VydmVyLT5jb2RlLCAk
c2VydmVyLT5tZXNzYWdlLCJUbyAkXyIsJHNlcnZlci0+cXVpdCk7DQoJCWRlbGV0ZSAkc2VsZi0+
eydjb25ueF9wZXJzaXN0J30tPnskY2hvc2VuaG9zdH07DQoJICAgICAgICByZXR1cm4gQHJldHZh
bDsNCiAgICAgICAgfQ0KDQogICAgICAgICRzZXJ2ZXItPmRhdGE7DQogICAgICAgICRzZXJ2ZXIt
PmRhdGFzZW5kKCRfKSBmb3JlYWNoIEBoZWFkZXI7DQogICAgICAgIG15ICRib2R5ZGF0YSA9ICRt
ZXNzYWdlLT5ib2R5LT5maWxlOw0KDQogICAgICAgIGlmKHJlZiAkYm9keWRhdGEgZXEgJ0dMT0In
KSB7ICRzZXJ2ZXItPmRhdGFzZW5kKCRfKSB3aGlsZSA8JGJvZHlkYXRhPiB9DQogICAgICAgIGVs
c2UgICAgeyB3aGlsZShteSAkbCA9ICRib2R5ZGF0YS0+Z2V0bGluZSkgeyAkc2VydmVyLT5kYXRh
c2VuZCgkbCkgfSB9DQoNCgl1bmxlc3MoJHNlcnZlci0+ZGF0YWVuZCkNCgl7DQoJCW15IEByZXR2
YWw9KDAsICRzZXJ2ZXItPmNvZGUsICRzZXJ2ZXItPm1lc3NhZ2UsICdEQVRBJywgJHNlcnZlci0+
cXVpdCk7DQoJCWRlbGV0ZSAkc2VsZi0+eydjb25ueF9wZXJzaXN0J30tPnskY2hvc2VuaG9zdH07
DQoJICAgICAgICByZXR1cm4gQHJldHZhbDsNCiAgICAJfQ0KDQogICAgICAgIHJldHVybiAoMSwg
JHNlcnZlci0+Y29kZSwgJHNlcnZlci0+bWVzc2FnZSwgJ05PT1AnLCAkc2VydmVyLT5jb2RlKTsN
CiAgICB9DQoNCgkjIGluIFNDQUxBUiBjb250ZXh0DQoJcmV0dXJuIDAgdW5sZXNzICRzZXJ2ZXI7
DQoNCgl1bmxlc3MoJHNlcnZlci0+bWFpbCgkZnJvbSkpDQoJew0KCQkkc2VydmVyLT5xdWl0Ow0K
CQlkZWxldGUgJHNlbGYtPnsnY29ubnhfcGVyc2lzdCd9LT57JGNob3Nlbmhvc3R9Ow0KCQlyZXR1
cm4gMDsNCgl9DQoNCglmb3JlYWNoIChAdG8pDQoJew0KCQluZXh0IGlmICRzZXJ2ZXItPnRvKCRf
KTsNCiMgbXVzdCB3ZSBiZSBhYmxlIHRvIGRpc2FibGUgdGhpcz8NCiMgbmV4dCBpZiAkYXJnc3tp
Z25vcmVfZXJyb25lb3VzX2Rlc3RpbmF0aW9uc30NCgkJJHNlcnZlci0+cXVpdDsNCgkJZGVsZXRl
ICRzZWxmLT57J2Nvbm54X3BlcnNpc3QnfS0+eyRjaG9zZW5ob3N0fTsNCgkJcmV0dXJuIDA7DQoJ
fQ0KDQoJJHNlcnZlci0+ZGF0YTsNCgkkc2VydmVyLT5kYXRhc2VuZCgkXykgZm9yZWFjaCBAaGVh
ZGVyOw0KCW15ICRib2R5ZGF0YSA9ICRtZXNzYWdlLT5ib2R5LT5maWxlOw0KDQoJaWYocmVmICRi
b2R5ZGF0YSBlcSAnR0xPQicpIHsgJHNlcnZlci0+ZGF0YXNlbmQoJF8pIHdoaWxlIDwkYm9keWRh
dGE+IH0NCgllbHNlICAgIHsgd2hpbGUobXkgJGwgPSAkYm9keWRhdGEtPmdldGxpbmUpIHsgJHNl
cnZlci0+ZGF0YXNlbmQoJGwpIH0gfQ0KDQoJdW5sZXNzKCRzZXJ2ZXItPmRhdGFlbmQpDQoJew0K
CSAgICAkc2VydmVyLT5xdWl0Ow0KCSAgICBkZWxldGUgJHNlbGYtPnsnY29ubnhfcGVyc2lzdCd9
LT57JGNob3Nlbmhvc3R9Ow0KCSAgICByZXR1cm4gMDsNCgl9DQoJMTsNCgkjIEVMUyBJbXBsaWNp
dCB1bmxvY2sgJHNlbGYtPnsnY29ubnhfcGVyc2lzdCd9LT57JGNob3Nlbmhvc3R9IGFzIGV4aXQg
c2NvcGU7DQp9DQoNCiMtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0N
Cg0KDQpzdWIgY29udGFjdEFueVNlcnZlcigpDQp7ICAgbXkgJHNlbGYgPSBzaGlmdDsNCg0KICAg
IG15ICgkZW50ZXJ2YWwsICRjb3VudCwgJHRpbWVvdXQpID0gJHNlbGYtPnJldHJ5Ow0KICAgIG15
ICgkaG9zdCwgJHBvcnQsICR1c2VybmFtZSwgJHBhc3N3b3JkKSA9ICRzZWxmLT5yZW1vdGVIb3N0
Ow0KICAgIG15IEBob3N0cyA9IHJlZiAkaG9zdCA/IEAkaG9zdCA6ICRob3N0Ow0KDQogICAgZm9y
ZWFjaCBteSAkaG9zdCAoQGhvc3RzKQ0KICAgIHsgICBteSAkc2VydmVyID0gJHNlbGYtPnRyeUNv
bm5lY3RUbw0KICAgICAgICAgKCAkaG9zdCwgUG9ydCA9PiAkcG9ydCwNCiAgICAgICAgICwgJXsk
c2VsZi0+e01UU19uZXRfc210cF9vcHRzfX0sIFRpbWVvdXQgPT4gJHRpbWVvdXQNCiAgICAgICAg
ICk7DQoNCiAgICAgICAgZGVmaW5lZCAkc2VydmVyIG9yIG5leHQ7DQoNCiAgICAgICAgJHNlbGYt
PmxvZyhQUk9HUkVTUyA9PiAiT3BlbmVkIFNNVFAgY29ubmVjdGlvbiB0byAkaG9zdC4iKTsNCg0K
ICAgICAgICBpZihkZWZpbmVkICR1c2VybmFtZSkNCiAgICAgICAgeyAgIGlmKCRzZXJ2ZXItPmF1
dGgoJHVzZXJuYW1lLCAkcGFzc3dvcmQpKQ0KICAgICAgICAgICAgeyAgICAkc2VsZi0+bG9nKFBS
T0dSRVNTID0+ICIkaG9zdDogQXV0aGVudGljYXRpb24gc3VjY2VlZGVkLiIpOw0KICAgICAgICAg
ICAgfQ0KICAgICAgICAgICAgZWxzZQ0KICAgICAgICAgICAgeyAgICAkc2VsZi0+bG9nKEVSUk9S
ID0+ICJBdXRoZW50aWNhdGlvbiBmYWlsZWQuIik7DQogICAgICAgICAgICAgICAgIHJldHVybiB1
bmRlZjsNCiAgICAgICAgICAgIH0NCiAgICAgICAgfQ0KDQogICAgICAgIHJldHVybiAkc2VydmVy
Ow0KICAgIH0NCg0KICAgIHVuZGVmOw0KfQ0KDQojLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t
LS0tLS0tLS0tLS0tLS0tDQoNCnN1YiBjb250YWN0QW55U2VydmVyX3BlcnNpc3QoKQ0KeyAgIG15
ICRzZWxmID0gc2hpZnQ7DQoNCiAgICBteSAoJGVudGVydmFsLCAkY291bnQsICR0aW1lb3V0KSA9
ICRzZWxmLT5yZXRyeTsNCiAgICBteSAoJGhvc3QsICRwb3J0LCAkdXNlcm5hbWUsICRwYXNzd29y
ZCkgPSAkc2VsZi0+cmVtb3RlSG9zdDsNCiAgICBteSBAaG9zdHMgPSByZWYgJGhvc3QgPyBAJGhv
c3QgOiAkaG9zdDsNCg0KICAgIGZvcmVhY2ggbXkgJGhvc3QgKEBob3N0cykNCiAgICB7ICAgbXkg
KCRzZXJ2ZXIpOw0KCSAgIGlmKGV4aXN0cygkc2VsZi0+eydjb25ueF9wZXJzaXN0J30tPnskaG9z
dH0pKSAjRUxTDQoJICAgew0KCQkgICAkc2VydmVyPSRzZWxmLT57J2Nvbm54X3BlcnNpc3QnfS0+
eyRob3N0fTsNCgkJICAgbG9jayAkc2VsZi0+eydjb25ueF9wZXJzaXN0J30tPnskaG9zdH0gaWYg
JHNlcnZlcjsNCgkJICAgdW5sZXNzICgkc2VydmVyLT5yZXNldCkNCgkJICAgew0KCQkJICAgZGVs
ZXRlKCRzZWxmLT57J2Nvbm54X3BlcnNpc3QnfS0+eyRob3N0fSk7DQoJCQkgICBuZXh0Ow0KCQkg
ICB9DQoJCSAgICMgSW1wbGljaXQgdW5sb2NrICRzZWxmLT57J2Nvbm54X3BlcnNpc3QnfS0+eyRo
b3N0fQ0KCSAgIH0NCgkgICBlbHNlDQoJICAgew0KCQkgICRzZXJ2ZXIgPSAkc2VsZi0+dHJ5Q29u
bmVjdFRvDQogICAgICAgCQkgICggJGhvc3QsIFBvcnQgPT4gJHBvcnQsDQogICAgICAgCQkgICwg
JXskc2VsZi0+e01UU19uZXRfc210cF9vcHRzfX0sIFRpbWVvdXQgPT4gJHRpbWVvdXQNCiAgICAg
ICAJCSAgKTsNCg0KCSAgICAgICAgZGVmaW5lZCAkc2VydmVyIG9yIG5leHQ7DQoJDQogICAgICAg
CQkgJHNlbGYtPmxvZyhQUk9HUkVTUyA9PiAiT3BlbmVkIFNNVFAgY29ubmVjdGlvbiB0byAkaG9z
dC4iKTsNCgkJDQogICAgICAgCQkgaWYoZGVmaW5lZCAkdXNlcm5hbWUpDQogICAgICAgCQkgeyAg
IGlmKCRzZXJ2ZXItPmF1dGgoJHVzZXJuYW1lLCAkcGFzc3dvcmQpKQ0KICAgICAgIAkJICAgICB7
ICAgICRzZWxmLT5sb2coUFJPR1JFU1MgPT4gIiRob3N0OiBBdXRoZW50aWNhdGlvbiBzdWNjZWVk
ZWQuIik7DQogICAgICAgCQkgICAgIH0NCiAgICAgICAJCSAgICAgZWxzZQ0KICAgICAgIAkJICAg
ICB7ICAgICRzZWxmLT5sb2coRVJST1IgPT4gIkF1dGhlbnRpY2F0aW9uIGZhaWxlZC4iKTsNCiAg
ICAgICAJCSAgICAgICAgICByZXR1cm4gdW5kZWY7DQogICAgICAgCQkgICAgIH0NCiAgICAgICAJ
CSB9DQoJCQ0KCQkgJHNlbGYtPnsnY29ubnhfcGVyc2lzdCd9LT57JGhvc3R9PSRzZXJ2ZXI7DQoJ
ICAgfQ0KICAgICAgICByZXR1cm4gKCRzZXJ2ZXIsJGhvc3QpOw0KICAgIH0NCg0KICAgIHVuZGVm
Ow0KfQ0KDQojLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tDQoNCg0K
c3ViIHRyeUNvbm5lY3RUbygkQCkNCnsgICBteSAoJHNlbGYsICRob3N0KSA9IChzaGlmdCwgc2hp
ZnQpOw0KICAgIE5ldDo6U01UUC0+bmV3KCRob3N0LCBAXyk7DQp9DQoNCiMtLS0tLS0tLS0tLS0t
LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0NCg0Kc3ViIERFU1RST1koJCkgICNFTFMNCnsN
CgkJbXkgJHNlbGY9c2hpZnQ7DQoJCWZvcmVhY2ggbXkgJGNvbm54ICh2YWx1ZXMgJXskc2VsZi0+
eydjb25ueF9wZXJzaXN0J319KQ0KCQl7DQoJCQkkY29ubngtPnF1aXQ7DQoJCX0NCn0NCg0KDQox
Ow0K

--=_mixed 007D6ED285257015_=--