LyoKICogJFhGcmVlODY6IHhjL2xpYi9mb250Y29uZmlnL3NyYy9mY3htbC5jLHYgMS4yMSAyMDAyLzA4LzIyIDE4OjUzOjIyIGtlaXRocCBFeHAgJAogKgogKiBDb3B5cmlnaHQgqSAyMDAyIEtlaXRoIFBhY2thcmQsIG1lbWJlciBvZiBUaGUgWEZyZWU4NiBQcm9qZWN0LCBJbmMuCiAqCiAqIFBlcm1pc3Npb24gdG8gdXNlLCBjb3B5LCBtb2RpZnksIGRpc3RyaWJ1dGUsIGFuZCBzZWxsIHRoaXMgc29mdHdhcmUgYW5kIGl0cwogKiBkb2N1bWVudGF0aW9uIGZvciBhbnkgcHVycG9zZSBpcyBoZXJlYnkgZ3JhbnRlZCB3aXRob3V0IGZlZSwgcHJvdmlkZWQgdGhhdAogKiB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSBhcHBlYXIgaW4gYWxsIGNvcGllcyBhbmQgdGhhdCBib3RoIHRoYXQKICogY29weXJpZ2h0IG5vdGljZSBhbmQgdGhpcyBwZXJtaXNzaW9uIG5vdGljZSBhcHBlYXIgaW4gc3VwcG9ydGluZwogKiBkb2N1bWVudGF0aW9uLCBhbmQgdGhhdCB0aGUgbmFtZSBvZiBLZWl0aCBQYWNrYXJkIG5vdCBiZSB1c2VkIGluCiAqIGFkdmVydGlzaW5nIG9yIHB1YmxpY2l0eSBwZXJ0YWluaW5nIHRvIGRpc3RyaWJ1dGlvbiBvZiB0aGUgc29mdHdhcmUgd2l0aG91dAogKiBzcGVjaWZpYywgd3JpdHRlbiBwcmlvciBwZXJtaXNzaW9uLiAgS2VpdGggUGFja2FyZCBtYWtlcyBubwogKiByZXByZXNlbnRhdGlvbnMgYWJvdXQgdGhlIHN1aXRhYmlsaXR5IG9mIHRoaXMgc29mdHdhcmUgZm9yIGFueSBwdXJwb3NlLiAgSXQKICogaXMgcHJvdmlkZWQgImFzIGlzIiB3aXRob3V0IGV4cHJlc3Mgb3IgaW1wbGllZCB3YXJyYW50eS4KICoKICogS0VJVEggUEFDS0FSRCBESVNDTEFJTVMgQUxMIFdBUlJBTlRJRVMgV0lUSCBSRUdBUkQgVE8gVEhJUyBTT0ZUV0FSRSwKICogSU5DTFVESU5HIEFMTCBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTLCBJTiBOTwogKiBFVkVOVCBTSEFMTCBLRUlUSCBQQUNLQVJEIEJFIExJQUJMRSBGT1IgQU5ZIFNQRUNJQUwsIElORElSRUNUIE9SCiAqIENPTlNFUVVFTlRJQUwgREFNQUdFUyBPUiBBTlkgREFNQUdFUyBXSEFUU09FVkVSIFJFU1VMVElORyBGUk9NIExPU1MgT0YgVVNFLAogKiBEQVRBIE9SIFBST0ZJVFMsIFdIRVRIRVIgSU4gQU4gQUNUSU9OIE9GIENPTlRSQUNULCBORUdMSUdFTkNFIE9SIE9USEVSCiAqIFRPUlRJT1VTIEFDVElPTiwgQVJJU0lORyBPVVQgT0YgT1IgSU4gQ09OTkVDVElPTiBXSVRIIFRIRSBVU0UgT1IKICogUEVSRk9STUFOQ0UgT0YgVEhJUyBTT0ZUV0FSRS4KICovCgojaW5jbHVkZSA8c3RkYXJnLmg+CiNpbmNsdWRlICJmY2ludC5oIgoKI2lmbmRlZiBIQVZFX1hNTFBBUlNFX0gKI2RlZmluZSBIQVZFX1hNTFBBUlNFX0ggMAojZW5kaWYKCiNpZiBIQVZFX1hNTFBBUlNFX0gKI2luY2x1ZGUgPHhtbHBhcnNlLmg+CiNlbHNlCiNpbmNsdWRlIDxleHBhdC5oPgojZW5kaWYKCkZjVGVzdCAqCkZjVGVzdENyZWF0ZSAoRmNNYXRjaEtpbmQgICBraW5kLCAKCSAgICAgIEZjUXVhbAkgICAgcXVhbCwKCSAgICAgIGNvbnN0IEZjQ2hhcjggKmZpZWxkLAoJICAgICAgRmNPcAkgICAgY29tcGFyZSwKCSAgICAgIEZjRXhwcgkgICAgKmV4cHIpCnsKICAgIEZjVGVzdAkqdGVzdCA9IChGY1Rlc3QgKikgbWFsbG9jIChzaXplb2YgKEZjVGVzdCkpOwoKICAgIGlmICh0ZXN0KQogICAgewoJRmNNZW1BbGxvYyAoRkNfTUVNX1RFU1QsIHNpemVvZiAoRmNUZXN0KSk7Cgl0ZXN0LT5uZXh0ID0gMDsKCXRlc3QtPmtpbmQgPSBraW5kOwoJdGVzdC0+cXVhbCA9IHF1YWw7Cgl0ZXN0LT5maWVsZCA9IChjaGFyICopIEZjU3RyQ29weSAoZmllbGQpOwoJdGVzdC0+b3AgPSBjb21wYXJlOwoJdGVzdC0+ZXhwciA9IGV4cHI7CiAgICB9CiAgICByZXR1cm4gdGVzdDsKfQoKdm9pZApGY1Rlc3REZXN0cm95IChGY1Rlc3QgKnRlc3QpCnsKICAgIGlmICh0ZXN0LT5uZXh0KQoJRmNUZXN0RGVzdHJveSAodGVzdC0+bmV4dCk7CiAgICBGY0V4cHJEZXN0cm95ICh0ZXN0LT5leHByKTsKICAgIEZjU3RyRnJlZSAoKEZjQ2hhcjggKikgdGVzdC0+ZmllbGQpOwogICAgRmNNZW1GcmVlIChGQ19NRU1fVEVTVCwgc2l6ZW9mIChGY1Rlc3QpKTsKICAgIGZyZWUgKHRlc3QpOwp9CgpGY0V4cHIgKgpGY0V4cHJDcmVhdGVJbnRlZ2VyIChpbnQgaSkKewogICAgRmNFeHByICplID0gKEZjRXhwciAqKSBtYWxsb2MgKHNpemVvZiAoRmNFeHByKSk7CgogICAgaWYgKGUpCiAgICB7CglGY01lbUFsbG9jIChGQ19NRU1fRVhQUiwgc2l6ZW9mIChGY0V4cHIpKTsKCWUtPm9wID0gRmNPcEludGVnZXI7CgllLT51Lml2YWwgPSBpOwogICAgfQogICAgcmV0dXJuIGU7Cn0KCkZjRXhwciAqCkZjRXhwckNyZWF0ZURvdWJsZSAoZG91YmxlIGQpCnsKICAgIEZjRXhwciAqZSA9IChGY0V4cHIgKikgbWFsbG9jIChzaXplb2YgKEZjRXhwcikpOwoKICAgIGlmIChlKQogICAgewoJRmNNZW1BbGxvYyAoRkNfTUVNX0VYUFIsIHNpemVvZiAoRmNFeHByKSk7CgllLT5vcCA9IEZjT3BEb3VibGU7CgllLT51LmR2YWwgPSBkOwogICAgfQogICAgcmV0dXJuIGU7Cn0KCkZjRXhwciAqCkZjRXhwckNyZWF0ZVN0cmluZyAoY29uc3QgRmNDaGFyOCAqcykKewogICAgRmNFeHByICplID0gKEZjRXhwciAqKSBtYWxsb2MgKHNpemVvZiAoRmNFeHByKSk7CgogICAgaWYgKGUpCiAgICB7CglGY01lbUFsbG9jIChGQ19NRU1fRVhQUiwgc2l6ZW9mIChGY0V4cHIpKTsKCWUtPm9wID0gRmNPcFN0cmluZzsKCWUtPnUuc3ZhbCA9IEZjU3RyQ29weSAocyk7CiAgICB9CiAgICByZXR1cm4gZTsKfQoKRmNFeHByICoKRmNFeHByQ3JlYXRlTWF0cml4IChjb25zdCBGY01hdHJpeCAqbSkKewogICAgRmNFeHByICplID0gKEZjRXhwciAqKSBtYWxsb2MgKHNpemVvZiAoRmNFeHByKSk7CgogICAgaWYgKGUpCiAgICB7CglGY01lbUFsbG9jIChGQ19NRU1fRVhQUiwgc2l6ZW9mIChGY0V4cHIpKTsKCWUtPm9wID0gRmNPcE1hdHJpeDsKCWUtPnUubXZhbCA9IEZjTWF0cml4Q29weSAobSk7CiAgICB9CiAgICByZXR1cm4gZTsKfQoKRmNFeHByICoKRmNFeHByQ3JlYXRlQm9vbCAoRmNCb29sIGIpCnsKICAgIEZjRXhwciAqZSA9IChGY0V4cHIgKikgbWFsbG9jIChzaXplb2YgKEZjRXhwcikpOwoKICAgIGlmIChlKQogICAgewoJRmNNZW1BbGxvYyAoRkNfTUVNX0VYUFIsIHNpemVvZiAoRmNFeHByKSk7CgllLT5vcCA9IEZjT3BCb29sOwoJZS0+dS5idmFsID0gYjsKICAgIH0KICAgIHJldHVybiBlOwp9CgpGY0V4cHIgKgpGY0V4cHJDcmVhdGVOaWwgKHZvaWQpCnsKICAgIEZjRXhwciAqZSA9IChGY0V4cHIgKikgbWFsbG9jIChzaXplb2YgKEZjRXhwcikpOwoKICAgIGlmIChlKQogICAgewoJRmNNZW1BbGxvYyAoRkNfTUVNX0VYUFIsIHNpemVvZiAoRmNFeHByKSk7CgllLT5vcCA9IEZjT3BOaWw7CiAgICB9CiAgICByZXR1cm4gZTsKfQoKRmNFeHByICoKRmNFeHByQ3JlYXRlRmllbGQgKGNvbnN0IGNoYXIgKmZpZWxkKQp7CiAgICBGY0V4cHIgKmUgPSAoRmNFeHByICopIG1hbGxvYyAoc2l6ZW9mIChGY0V4cHIpKTsKCiAgICBpZiAoZSkKICAgIHsKCUZjTWVtQWxsb2MgKEZDX01FTV9FWFBSLCBzaXplb2YgKEZjRXhwcikpOwoJZS0+b3AgPSBGY09wRmllbGQ7CgllLT51LmZpZWxkID0gKGNoYXIgKikgRmNTdHJDb3B5ICgoRmNDaGFyOCAqKSBmaWVsZCk7CiAgICB9CiAgICByZXR1cm4gZTsKfQoKRmNFeHByICoKRmNFeHByQ3JlYXRlQ29uc3QgKGNvbnN0IEZjQ2hhcjggKmNvbnN0YW50KQp7CiAgICBGY0V4cHIgKmUgPSAoRmNFeHByICopIG1hbGxvYyAoc2l6ZW9mIChGY0V4cHIpKTsKCiAgICBpZiAoZSkKICAgIHsKCUZjTWVtQWxsb2MgKEZDX01FTV9FWFBSLCBzaXplb2YgKEZjRXhwcikpOwoJZS0+b3AgPSBGY09wQ29uc3Q7CgllLT51LmNvbnN0YW50ID0gRmNTdHJDb3B5IChjb25zdGFudCk7CiAgICB9CiAgICByZXR1cm4gZTsKfQoKRmNFeHByICoKRmNFeHByQ3JlYXRlT3AgKEZjRXhwciAqbGVmdCwgRmNPcCBvcCwgRmNFeHByICpyaWdodCkKewogICAgRmNFeHByICplID0gKEZjRXhwciAqKSBtYWxsb2MgKHNpemVvZiAoRmNFeHByKSk7CgogICAgaWYgKGUpCiAgICB7CglGY01lbUFsbG9jIChGQ19NRU1fRVhQUiwgc2l6ZW9mIChGY0V4cHIpKTsKCWUtPm9wID0gb3A7CgllLT51LnRyZWUubGVmdCA9IGxlZnQ7CgllLT51LnRyZWUucmlnaHQgPSByaWdodDsKICAgIH0KICAgIHJldHVybiBlOwp9Cgp2b2lkCkZjRXhwckRlc3Ryb3kgKEZjRXhwciAqZSkKewogICAgc3dpdGNoIChlLT5vcCkgewogICAgY2FzZSBGY09wSW50ZWdlcjoKCWJyZWFrOwogICAgY2FzZSBGY09wRG91YmxlOgoJYnJlYWs7CiAgICBjYXNlIEZjT3BTdHJpbmc6CglGY1N0ckZyZWUgKGUtPnUuc3ZhbCk7CglicmVhazsKICAgIGNhc2UgRmNPcE1hdHJpeDoKCUZjTWF0cml4RnJlZSAoZS0+dS5tdmFsKTsKCWJyZWFrOwogICAgY2FzZSBGY09wQ2hhclNldDoKCUZjQ2hhclNldERlc3Ryb3kgKGUtPnUuY3ZhbCk7CglicmVhazsKICAgIGNhc2UgRmNPcEJvb2w6CglicmVhazsKICAgIGNhc2UgRmNPcEZpZWxkOgoJRmNTdHJGcmVlICgoRmNDaGFyOCAqKSBlLT51LmZpZWxkKTsKCWJyZWFrOwogICAgY2FzZSBGY09wQ29uc3Q6CglGY1N0ckZyZWUgKGUtPnUuY29uc3RhbnQpOwoJYnJlYWs7CiAgICBjYXNlIEZjT3BBc3NpZ246CiAgICBjYXNlIEZjT3BBc3NpZ25SZXBsYWNlOgogICAgY2FzZSBGY09wUHJlcGVuZDoKICAgIGNhc2UgRmNPcFByZXBlbmRGaXJzdDoKICAgIGNhc2UgRmNPcEFwcGVuZDoKICAgIGNhc2UgRmNPcEFwcGVuZExhc3Q6CglicmVhazsKICAgIGNhc2UgRmNPcE9yOgogICAgY2FzZSBGY09wQW5kOgogICAgY2FzZSBGY09wRXF1YWw6CiAgICBjYXNlIEZjT3BOb3RFcXVhbDoKICAgIGNhc2UgRmNPcExlc3M6CiAgICBjYXNlIEZjT3BMZXNzRXF1YWw6CiAgICBjYXNlIEZjT3BNb3JlOgogICAgY2FzZSBGY09wTW9yZUVxdWFsOgogICAgY2FzZSBGY09wQ29udGFpbnM6CiAgICBjYXNlIEZjT3BOb3RDb250YWluczoKICAgIGNhc2UgRmNPcFBsdXM6CiAgICBjYXNlIEZjT3BNaW51czoKICAgIGNhc2UgRmNPcFRpbWVzOgogICAgY2FzZSBGY09wRGl2aWRlOgogICAgY2FzZSBGY09wUXVlc3Q6CiAgICBjYXNlIEZjT3BDb21tYToKCUZjRXhwckRlc3Ryb3kgKGUtPnUudHJlZS5yaWdodCk7CgkvKiBmYWxsIHRocm91Z2ggKi8KICAgIGNhc2UgRmNPcE5vdDoKCUZjRXhwckRlc3Ryb3kgKGUtPnUudHJlZS5sZWZ0KTsKCWJyZWFrOwogICAgY2FzZSBGY09wTmlsOgogICAgY2FzZSBGY09wSW52YWxpZDoKCWJyZWFrOwogICAgfQogICAgRmNNZW1GcmVlIChGQ19NRU1fRVhQUiwgc2l6ZW9mIChGY0V4cHIpKTsKICAgIGZyZWUgKGUpOwp9CgpGY0VkaXQgKgpGY0VkaXRDcmVhdGUgKGNvbnN0IGNoYXIgKmZpZWxkLCBGY09wIG9wLCBGY0V4cHIgKmV4cHIsIEZjVmFsdWVCaW5kaW5nIGJpbmRpbmcpCnsKICAgIEZjRWRpdCAqZSA9IChGY0VkaXQgKikgbWFsbG9jIChzaXplb2YgKEZjRWRpdCkpOwoKICAgIGlmIChlKQogICAgewoJZS0+bmV4dCA9IDA7CgllLT5maWVsZCA9IGZpZWxkOyAgIC8qIGFscmVhZHkgc2F2ZWQgaW4gZ3JhbW1hciAqLwoJZS0+b3AgPSBvcDsKCWUtPmV4cHIgPSBleHByOwoJZS0+YmluZGluZyA9IGJpbmRpbmc7CiAgICB9CiAgICByZXR1cm4gZTsKfQoKdm9pZApGY0VkaXREZXN0cm95IChGY0VkaXQgKmUpCnsKICAgIGlmIChlLT5uZXh0KQoJRmNFZGl0RGVzdHJveSAoZS0+bmV4dCk7CiAgICBGY1N0ckZyZWUgKChGY0NoYXI4ICopIGUtPmZpZWxkKTsKICAgIGlmIChlLT5leHByKQoJRmNFeHByRGVzdHJveSAoZS0+ZXhwcik7Cn0KCmNoYXIgKgpGY0NvbmZpZ1NhdmVGaWVsZCAoY29uc3QgY2hhciAqZmllbGQpCnsKICAgIHJldHVybiAoY2hhciAqKSBGY1N0ckNvcHkgKChGY0NoYXI4ICopIGZpZWxkKTsKfQoKdHlwZWRlZiBlbnVtIF9GY0VsZW1lbnQgewogICAgRmNFbGVtZW50Tm9uZSwKICAgIEZjRWxlbWVudEZvbnRjb25maWcsCiAgICBGY0VsZW1lbnREaXIsCiAgICBGY0VsZW1lbnRDYWNoZSwKICAgIEZjRWxlbWVudEluY2x1ZGUsCiAgICBGY0VsZW1lbnRDb25maWcsCiAgICBGY0VsZW1lbnRNYXRjaCwKICAgIEZjRWxlbWVudEFsaWFzLAoJCiAgICBGY0VsZW1lbnRCbGFuaywKICAgIEZjRWxlbWVudFJlc2NhbiwKCiAgICBGY0VsZW1lbnRQcmVmZXIsCiAgICBGY0VsZW1lbnRBY2NlcHQsCiAgICBGY0VsZW1lbnREZWZhdWx0LAogICAgRmNFbGVtZW50RmFtaWx5LAoKICAgIEZjRWxlbWVudFRlc3QsCiAgICBGY0VsZW1lbnRFZGl0LAogICAgRmNFbGVtZW50SW50LAogICAgRmNFbGVtZW50RG91YmxlLAogICAgRmNFbGVtZW50U3RyaW5nLAogICAgRmNFbGVtZW50TWF0cml4LAogICAgRmNFbGVtZW50Qm9vbCwKICAgIEZjRWxlbWVudENoYXJzZXQsCiAgICBGY0VsZW1lbnROYW1lLAogICAgRmNFbGVtZW50Q29uc3QsCiAgICBGY0VsZW1lbnRPciwKICAgIEZjRWxlbWVudEFuZCwKICAgIEZjRWxlbWVudEVxLAogICAgRmNFbGVtZW50Tm90RXEsCiAgICBGY0VsZW1lbnRMZXNzLAogICAgRmNFbGVtZW50TGVzc0VxLAogICAgRmNFbGVtZW50TW9yZSwKICAgIEZjRWxlbWVudE1vcmVFcSwKICAgIEZjRWxlbWVudENvbnRhaW5zLAogICAgRmNFbGVtZW50Tm90Q29udGFpbnMsCiAgICBGY0VsZW1lbnRQbHVzLAogICAgRmNFbGVtZW50TWludXMsCiAgICBGY0VsZW1lbnRUaW1lcywKICAgIEZjRWxlbWVudERpdmlkZSwKICAgIEZjRWxlbWVudE5vdCwKICAgIEZjRWxlbWVudElmLAogICAgRmNFbGVtZW50VW5rbm93bgp9IEZjRWxlbWVudDsKCnN0YXRpYyBGY0VsZW1lbnQKRmNFbGVtZW50TWFwIChjb25zdCBYTUxfQ2hhciAqbmFtZSkKewogICAgc3RhdGljIHN0cnVjdCB7CgljaGFyCSAgICAqbmFtZTsKCUZjRWxlbWVudCAgIGVsZW1lbnQ7CiAgICB9IGZjRWxlbWVudE1hcFtdID0gewoJeyAiZm9udGNvbmZpZyIsCUZjRWxlbWVudEZvbnRjb25maWcgfSwKCXsgImRpciIsCUZjRWxlbWVudERpciB9LAoJeyAiY2FjaGUiLAlGY0VsZW1lbnRDYWNoZSB9LAoJeyAiaW5jbHVkZSIsCUZjRWxlbWVudEluY2x1ZGUgfSwKCXsgImNvbmZpZyIsCUZjRWxlbWVudENvbmZpZyB9LAoJeyAibWF0Y2giLAlGY0VsZW1lbnRNYXRjaCB9LAoJeyAiYWxpYXMiLAlGY0VsZW1lbnRBbGlhcyB9LAoJCgl7ICJibGFuayIsCUZjRWxlbWVudEJsYW5rIH0sCgl7ICJyZXNjYW4iLAlGY0VsZW1lbnRSZXNjYW4gfSwKCgl7ICJwcmVmZXIiLAlGY0VsZW1lbnRQcmVmZXIgfSwKCXsgImFjY2VwdCIsCUZjRWxlbWVudEFjY2VwdCB9LAoJeyAiZGVmYXVsdCIsCUZjRWxlbWVudERlZmF1bHQgfSwKCXsgImZhbWlseSIsCUZjRWxlbWVudEZhbWlseSB9LAoKCXsgInRlc3QiLAlGY0VsZW1lbnRUZXN0IH0sCgl7ICJlZGl0IiwJRmNFbGVtZW50RWRpdCB9LAoJeyAiaW50IiwJRmNFbGVtZW50SW50IH0sCgl7ICJkb3VibGUiLAlGY0VsZW1lbnREb3VibGUgfSwKCXsgInN0cmluZyIsCUZjRWxlbWVudFN0cmluZyB9LAoJeyAibWF0cml4IiwJRmNFbGVtZW50TWF0cml4IH0sCgl7ICJib29sIiwJRmNFbGVtZW50Qm9vbCB9LAoJeyAiY2hhcnNldCIsCUZjRWxlbWVudENoYXJzZXQgfSwKCXsgIm5hbWUiLAlGY0VsZW1lbnROYW1lIH0sCgl7ICJjb25zdCIsCUZjRWxlbWVudENvbnN0IH0sCgl7ICJvciIsCQlGY0VsZW1lbnRPciB9LAoJeyAiYW5kIiwJRmNFbGVtZW50QW5kIH0sCgl7ICJlcSIsCQlGY0VsZW1lbnRFcSB9LAoJeyAibm90X2VxIiwJRmNFbGVtZW50Tm90RXEgfSwKCXsgImxlc3MiLAlGY0VsZW1lbnRMZXNzIH0sCgl7ICJsZXNzX2VxIiwJRmNFbGVtZW50TGVzc0VxIH0sCgl7ICJtb3JlIiwJRmNFbGVtZW50TW9yZSB9LAoJeyAibW9yZV9lcSIsCUZjRWxlbWVudE1vcmVFcSB9LAoJeyAiY29udGFpbnMiLAlGY0VsZW1lbnRDb250YWlucyB9LAoJeyAibm90X2NvbnRhaW5zIixGY0VsZW1lbnROb3RDb250YWlucyB9LAoJeyAicGx1cyIsCUZjRWxlbWVudFBsdXMgfSwKCXsgIm1pbnVzIiwJRmNFbGVtZW50TWludXMgfSwKCXsgInRpbWVzIiwJRmNFbGVtZW50VGltZXMgfSwKCXsgImRpdmlkZSIsCUZjRWxlbWVudERpdmlkZSB9LAoJeyAibm90IiwJRmNFbGVtZW50Tm90IH0sCgl7ICJpZiIsCQlGY0VsZW1lbnRJZiB9LAoJCgl7IDAsCQkwIH0KICAgIH07CgogICAgaW50CSAgICBpOwogICAgZm9yIChpID0gMDsgZmNFbGVtZW50TWFwW2ldLm5hbWU7IGkrKykKCWlmICghc3RyY21wICgoY2hhciAqKSBuYW1lLCBmY0VsZW1lbnRNYXBbaV0ubmFtZSkpCgkgICAgcmV0dXJuIGZjRWxlbWVudE1hcFtpXS5lbGVtZW50OwogICAgcmV0dXJuIEZjRWxlbWVudFVua25vd247Cn0KCnR5cGVkZWYgc3RydWN0IF9GY1BTdGFjayB7CiAgICBzdHJ1Y3QgX0ZjUFN0YWNrICAgKnByZXY7CiAgICBGY0VsZW1lbnQJCWVsZW1lbnQ7CiAgICBGY0NoYXI4CQkqKmF0dHI7CiAgICBGY1N0ckJ1ZgkJc3RyOwp9IEZjUFN0YWNrOwogICAgCnR5cGVkZWYgZW51bSBfRmNWU3RhY2tUYWcgewogICAgRmNWU3RhY2tOb25lLAoKICAgIEZjVlN0YWNrU3RyaW5nLAogICAgRmNWU3RhY2tGYW1pbHksCiAgICBGY1ZTdGFja0ZpZWxkLAogICAgRmNWU3RhY2tDb25zdGFudCwKICAgIAogICAgRmNWU3RhY2tQcmVmZXIsCiAgICBGY1ZTdGFja0FjY2VwdCwKICAgIEZjVlN0YWNrRGVmYXVsdCwKICAgIAogICAgRmNWU3RhY2tJbnRlZ2VyLAogICAgRmNWU3RhY2tEb3VibGUsCiAgICBGY1ZTdGFja01hdHJpeCwKICAgIEZjVlN0YWNrQm9vbCwKICAgIAogICAgRmNWU3RhY2tUZXN0LAogICAgRmNWU3RhY2tFeHByLAogICAgRmNWU3RhY2tFZGl0Cn0gRmNWU3RhY2tUYWc7Cgp0eXBlZGVmIHN0cnVjdCBfRmNWU3RhY2sgewogICAgc3RydWN0IF9GY1ZTdGFjawkqcHJldjsKICAgIEZjUFN0YWNrCQkqcHN0YWNrOwkvKiByZWxhdGVkIHBhcnNlIGVsZW1lbnQgKi8KICAgIEZjVlN0YWNrVGFnCQl0YWc7CiAgICB1bmlvbiB7CglGY0NoYXI4CQkqc3RyaW5nOwoKCWludAkJaW50ZWdlcjsKCWRvdWJsZQkJX2RvdWJsZTsKCUZjTWF0cml4CSptYXRyaXg7CglGY0Jvb2wJCWJvb2w7CgoJRmNUZXN0CQkqdGVzdDsKCUZjUXVhbAkJcXVhbDsKCUZjT3AJCW9wOwoJRmNFeHByCQkqZXhwcjsKCUZjRWRpdAkJKmVkaXQ7CiAgICB9IHU7Cn0gRmNWU3RhY2s7Cgp0eXBlZGVmIHN0cnVjdCBfRmNDb25maWdQYXJzZSB7CiAgICBGY1BTdGFjawkgICAgKnBzdGFjazsKICAgIEZjVlN0YWNrCSAgICAqdnN0YWNrOwogICAgRmNCb29sCSAgICBlcnJvcjsKICAgIGNvbnN0IEZjQ2hhcjggICAqbmFtZTsKICAgIEZjQ29uZmlnCSAgICAqY29uZmlnOwogICAgWE1MX1BhcnNlcgkgICAgcGFyc2VyOwp9IEZjQ29uZmlnUGFyc2U7Cgp0eXBlZGVmIGVudW0gX0ZjQ29uZmlnU2V2ZXJpdHkgewogICAgRmNTZXZlcmVJbmZvLCBGY1NldmVyZVdhcm5pbmcsIEZjU2V2ZXJlRXJyb3IKfSBGY0NvbmZpZ1NldmVyaXR5OwoKc3RhdGljIHZvaWQKRmNDb25maWdNZXNzYWdlIChGY0NvbmZpZ1BhcnNlICpwYXJzZSwgRmNDb25maWdTZXZlcml0eSBzZXZlcmUsIGNoYXIgKmZtdCwgLi4uKQp7CiAgICBjaGFyCSpzID0gInVua25vd24iOwogICAgdmFfbGlzdAlhcmdzOwoKICAgIHZhX3N0YXJ0IChhcmdzLCBmbXQpOwoKICAgIHN3aXRjaCAoc2V2ZXJlKSB7CiAgICBjYXNlIEZjU2V2ZXJlSW5mbzogcyA9ICJpbmZvIjsgYnJlYWs7CiAgICBjYXNlIEZjU2V2ZXJlV2FybmluZzogcyA9ICJ3YXJuaW5nIjsgYnJlYWs7CiAgICBjYXNlIEZjU2V2ZXJlRXJyb3I6IHMgPSAiZXJyb3IiOyBicmVhazsKICAgIH0KICAgIGlmIChwYXJzZSkKICAgIHsKCWlmIChwYXJzZS0+bmFtZSkKCSAgICBmcHJpbnRmIChzdGRlcnIsICJGb250Y29uZmlnICVzOiBcIiVzXCIsIGxpbmUgJWQ6ICIsIHMsCgkJICAgICBwYXJzZS0+bmFtZSwgWE1MX0dldEN1cnJlbnRMaW5lTnVtYmVyIChwYXJzZS0+cGFyc2VyKSk7CgllbHNlCgkgICAgZnByaW50ZiAoc3RkZXJyLCAiRm9udGNvbmZpZyAlczogbGluZSAlZDogIiwgcywKCQkgICAgIFhNTF9HZXRDdXJyZW50TGluZU51bWJlciAocGFyc2UtPnBhcnNlcikpOwoJaWYgKHNldmVyZSA+PSBGY1NldmVyZUVycm9yKQoJICAgIHBhcnNlLT5lcnJvciA9IEZjVHJ1ZTsKICAgIH0KICAgIGVsc2UKCWZwcmludGYgKHN0ZGVyciwgIkZvbnRjb25maWcgJXM6ICIsIHMpOwogICAgdmZwcmludGYgKHN0ZGVyciwgZm10LCBhcmdzKTsKICAgIGZwcmludGYgKHN0ZGVyciwgIlxuIik7CiAgICB2YV9lbmQgKGFyZ3MpOwp9CgpzdGF0aWMgdm9pZApGY1ZTdGFja1B1c2ggKEZjQ29uZmlnUGFyc2UgKnBhcnNlLCBGY1ZTdGFjayAqdnN0YWNrKQp7CiAgICB2c3RhY2stPnByZXYgPSBwYXJzZS0+dnN0YWNrOwogICAgdnN0YWNrLT5wc3RhY2sgPSBwYXJzZS0+cHN0YWNrID8gcGFyc2UtPnBzdGFjay0+cHJldiA6IDA7CiAgICBwYXJzZS0+dnN0YWNrID0gdnN0YWNrOwp9CgpzdGF0aWMgRmNWU3RhY2sgKgpGY1ZTdGFja0NyZWF0ZSAodm9pZCkKewogICAgRmNWU3RhY2sgICAgKm5ldzsKCiAgICBuZXcgPSBtYWxsb2MgKHNpemVvZiAoRmNWU3RhY2spKTsKICAgIGlmICghbmV3KQoJcmV0dXJuIDA7CiAgICBGY01lbUFsbG9jIChGQ19NRU1fVlNUQUNLLCBzaXplb2YgKEZjVlN0YWNrKSk7CiAgICBuZXctPnRhZyA9IEZjVlN0YWNrTm9uZTsKICAgIG5ldy0+cHJldiA9IDA7CiAgICByZXR1cm4gbmV3Owp9CgpzdGF0aWMgdm9pZApGY1ZTdGFja0Rlc3Ryb3kgKEZjVlN0YWNrICp2c3RhY2spCnsKICAgIEZjVlN0YWNrICAgICpwcmV2OwoKICAgIGZvciAoOyB2c3RhY2s7IHZzdGFjayA9IHByZXYpCiAgICB7CglwcmV2ID0gdnN0YWNrLT5wcmV2OwoJc3dpdGNoICh2c3RhY2stPnRhZykgewoJY2FzZSBGY1ZTdGFja05vbmU6CgkgICAgYnJlYWs7CgljYXNlIEZjVlN0YWNrU3RyaW5nOgoJY2FzZSBGY1ZTdGFja0ZhbWlseToKCWNhc2UgRmNWU3RhY2tGaWVsZDoKCWNhc2UgRmNWU3RhY2tDb25zdGFudDoKCSAgICBGY1N0ckZyZWUgKHZzdGFjay0+dS5zdHJpbmcpOwoJICAgIGJyZWFrOwoJY2FzZSBGY1ZTdGFja0ludGVnZXI6CgljYXNlIEZjVlN0YWNrRG91YmxlOgoJICAgIGJyZWFrOwoJY2FzZSBGY1ZTdGFja01hdHJpeDoKCSAgICBGY01hdHJpeEZyZWUgKHZzdGFjay0+dS5tYXRyaXgpOwoJICAgIGJyZWFrOwoJY2FzZSBGY1ZTdGFja0Jvb2w6CgkgICAgYnJlYWs7CgljYXNlIEZjVlN0YWNrVGVzdDoKCSAgICBGY1Rlc3REZXN0cm95ICh2c3RhY2stPnUudGVzdCk7CgkgICAgYnJlYWs7CgljYXNlIEZjVlN0YWNrRXhwcjoKCWNhc2UgRmNWU3RhY2tQcmVmZXI6CgljYXNlIEZjVlN0YWNrQWNjZXB0OgoJY2FzZSBGY1ZTdGFja0RlZmF1bHQ6CgkgICAgRmNFeHByRGVzdHJveSAodnN0YWNrLT51LmV4cHIpOwoJICAgIGJyZWFrOwoJY2FzZSBGY1ZTdGFja0VkaXQ6CgkgICAgRmNFZGl0RGVzdHJveSAodnN0YWNrLT51LmVkaXQpOwoJICAgIGJyZWFrOwoJfQoJRmNNZW1GcmVlIChGQ19NRU1fVlNUQUNLLCBzaXplb2YgKEZjVlN0YWNrKSk7CglmcmVlICh2c3RhY2spOwogICAgfQp9CgpzdGF0aWMgRmNCb29sCkZjVlN0YWNrUHVzaFN0cmluZyAoRmNDb25maWdQYXJzZSAqcGFyc2UsIEZjVlN0YWNrVGFnIHRhZywgRmNDaGFyOCAqc3RyaW5nKQp7CiAgICBGY1ZTdGFjayAgICAqdnN0YWNrID0gRmNWU3RhY2tDcmVhdGUgKCk7CiAgICBpZiAoIXZzdGFjaykKCXJldHVybiBGY0ZhbHNlOwogICAgdnN0YWNrLT51LnN0cmluZyA9IHN0cmluZzsKICAgIHZzdGFjay0+dGFnID0gdGFnOwogICAgRmNWU3RhY2tQdXNoIChwYXJzZSwgdnN0YWNrKTsKICAgIHJldHVybiBGY1RydWU7Cn0KCnN0YXRpYyBGY0Jvb2wKRmNWU3RhY2tQdXNoSW50ZWdlciAoRmNDb25maWdQYXJzZSAqcGFyc2UsIGludCBpbnRlZ2VyKQp7CiAgICBGY1ZTdGFjayAgICAqdnN0YWNrID0gRmNWU3RhY2tDcmVhdGUgKCk7CiAgICBpZiAoIXZzdGFjaykKCXJldHVybiBGY0ZhbHNlOwogICAgdnN0YWNrLT51LmludGVnZXIgPSBpbnRlZ2VyOwogICAgdnN0YWNrLT50YWcgPSBGY1ZTdGFja0ludGVnZXI7CiAgICBGY1ZTdGFja1B1c2ggKHBhcnNlLCB2c3RhY2spOwogICAgcmV0dXJuIEZjVHJ1ZTsKfQoKc3RhdGljIEZjQm9vbApGY1ZTdGFja1B1c2hEb3VibGUgKEZjQ29uZmlnUGFyc2UgKnBhcnNlLCBkb3VibGUgX2RvdWJsZSkKewogICAgRmNWU3RhY2sgICAgKnZzdGFjayA9IEZjVlN0YWNrQ3JlYXRlICgpOwogICAgaWYgKCF2c3RhY2spCglyZXR1cm4gRmNGYWxzZTsKICAgIHZzdGFjay0+dS5fZG91YmxlID0gX2RvdWJsZTsKICAgIHZzdGFjay0+dGFnID0gRmNWU3RhY2tEb3VibGU7CiAgICBGY1ZTdGFja1B1c2ggKHBhcnNlLCB2c3RhY2spOwogICAgcmV0dXJuIEZjVHJ1ZTsKfQoKc3RhdGljIEZjQm9vbApGY1ZTdGFja1B1c2hNYXRyaXggKEZjQ29uZmlnUGFyc2UgKnBhcnNlLCBGY01hdHJpeCAqbWF0cml4KQp7CiAgICBGY1ZTdGFjayAgICAqdnN0YWNrID0gRmNWU3RhY2tDcmVhdGUgKCk7CiAgICBpZiAoIXZzdGFjaykKCXJldHVybiBGY0ZhbHNlOwogICAgbWF0cml4ID0gRmNNYXRyaXhDb3B5IChtYXRyaXgpOwogICAgaWYgKCFtYXRyaXgpCiAgICB7CglGY1ZTdGFja0Rlc3Ryb3kgKHZzdGFjayk7CglyZXR1cm4gRmNGYWxzZTsKICAgIH0KICAgIHZzdGFjay0+dS5tYXRyaXggPSBtYXRyaXg7CiAgICB2c3RhY2stPnRhZyA9IEZjVlN0YWNrTWF0cml4OwogICAgRmNWU3RhY2tQdXNoIChwYXJzZSwgdnN0YWNrKTsKICAgIHJldHVybiBGY1RydWU7Cn0KCnN0YXRpYyBGY0Jvb2wKRmNWU3RhY2tQdXNoQm9vbCAoRmNDb25maWdQYXJzZSAqcGFyc2UsIEZjQm9vbCBib29sKQp7CiAgICBGY1ZTdGFjayAgICAqdnN0YWNrID0gRmNWU3RhY2tDcmVhdGUgKCk7CiAgICBpZiAoIXZzdGFjaykKCXJldHVybiBGY0ZhbHNlOwogICAgdnN0YWNrLT51LmJvb2wgPSBib29sOwogICAgdnN0YWNrLT50YWcgPSBGY1ZTdGFja0Jvb2w7CiAgICBGY1ZTdGFja1B1c2ggKHBhcnNlLCB2c3RhY2spOwogICAgcmV0dXJuIEZjVHJ1ZTsKfQoKc3RhdGljIEZjQm9vbApGY1ZTdGFja1B1c2hUZXN0IChGY0NvbmZpZ1BhcnNlICpwYXJzZSwgRmNUZXN0ICp0ZXN0KQp7CiAgICBGY1ZTdGFjayAgICAqdnN0YWNrID0gRmNWU3RhY2tDcmVhdGUgKCk7CiAgICBpZiAoIXZzdGFjaykKCXJldHVybiBGY0ZhbHNlOwogICAgdnN0YWNrLT51LnRlc3QgPSB0ZXN0OwogICAgdnN0YWNrLT50YWcgPSBGY1ZTdGFja1Rlc3Q7CiAgICBGY1ZTdGFja1B1c2ggKHBhcnNlLCB2c3RhY2spOwogICAgcmV0dXJuIEZjVHJ1ZTsKfQoKc3RhdGljIEZjQm9vbApGY1ZTdGFja1B1c2hFeHByIChGY0NvbmZpZ1BhcnNlICpwYXJzZSwgRmNWU3RhY2tUYWcgdGFnLCBGY0V4cHIgKmV4cHIpCnsKICAgIEZjVlN0YWNrICAgICp2c3RhY2sgPSBGY1ZTdGFja0NyZWF0ZSAoKTsKICAgIGlmICghdnN0YWNrKQoJcmV0dXJuIEZjRmFsc2U7CiAgICB2c3RhY2stPnUuZXhwciA9IGV4cHI7CiAgICB2c3RhY2stPnRhZyA9IHRhZzsKICAgIEZjVlN0YWNrUHVzaCAocGFyc2UsIHZzdGFjayk7CiAgICByZXR1cm4gRmNUcnVlOwp9CgpzdGF0aWMgRmNCb29sCkZjVlN0YWNrUHVzaEVkaXQgKEZjQ29uZmlnUGFyc2UgKnBhcnNlLCBGY0VkaXQgKmVkaXQpCnsKICAgIEZjVlN0YWNrICAgICp2c3RhY2sgPSBGY1ZTdGFja0NyZWF0ZSAoKTsKICAgIGlmICghdnN0YWNrKQoJcmV0dXJuIEZjRmFsc2U7CiAgICB2c3RhY2stPnUuZWRpdCA9IGVkaXQ7CiAgICB2c3RhY2stPnRhZyA9IEZjVlN0YWNrRWRpdDsKICAgIEZjVlN0YWNrUHVzaCAocGFyc2UsIHZzdGFjayk7CiAgICByZXR1cm4gRmNUcnVlOwp9CgpzdGF0aWMgRmNWU3RhY2sgKgpGY1ZTdGFja0ZldGNoIChGY0NvbmZpZ1BhcnNlICpwYXJzZSwgaW50IG9mZikKewogICAgRmNWU3RhY2sgICAgKnZzdGFjazsKCiAgICBmb3IgKHZzdGFjayA9IHBhcnNlLT52c3RhY2s7IHZzdGFjayAmJiBvZmYtLSA+IDA7IHZzdGFjayA9IHZzdGFjay0+cHJldik7CiAgICByZXR1cm4gdnN0YWNrOwp9CgpzdGF0aWMgdm9pZApGY1ZTdGFja0NsZWFyIChGY0NvbmZpZ1BhcnNlICpwYXJzZSkKewogICAgd2hpbGUgKHBhcnNlLT52c3RhY2sgJiYgcGFyc2UtPnZzdGFjay0+cHN0YWNrID09IHBhcnNlLT5wc3RhY2spCiAgICB7CglGY1ZTdGFjayAgICAqdnN0YWNrID0gcGFyc2UtPnZzdGFjazsKCXBhcnNlLT52c3RhY2sgPSB2c3RhY2stPnByZXY7Cgl2c3RhY2stPnByZXYgPSAwOwoJRmNWU3RhY2tEZXN0cm95ICh2c3RhY2spOwogICAgfQp9CgpzdGF0aWMgRmNWU3RhY2sgKgpGY1ZTdGFja1BvcCAoRmNDb25maWdQYXJzZSAqcGFyc2UpCnsKICAgIEZjVlN0YWNrCSp2c3RhY2sgPSBwYXJzZS0+dnN0YWNrOwogICAgCiAgICBpZiAoIXZzdGFjayB8fCB2c3RhY2stPnBzdGFjayAhPSBwYXJzZS0+cHN0YWNrKQoJcmV0dXJuIDA7CiAgICBwYXJzZS0+dnN0YWNrID0gdnN0YWNrLT5wcmV2OwogICAgdnN0YWNrLT5wcmV2ID0gMDsKICAgIHJldHVybiB2c3RhY2s7Cn0KCnN0YXRpYyBpbnQKRmNWU3RhY2tFbGVtZW50cyAoRmNDb25maWdQYXJzZSAqcGFyc2UpCnsKICAgIGludAkJaCA9IDA7CiAgICBGY1ZTdGFjawkqdnN0YWNrID0gcGFyc2UtPnZzdGFjazsKICAgIHdoaWxlICh2c3RhY2sgJiYgdnN0YWNrLT5wc3RhY2sgPT0gcGFyc2UtPnBzdGFjaykKICAgIHsKCWgrKzsKCXZzdGFjayA9IHZzdGFjay0+cHJldjsKICAgIH0KICAgIHJldHVybiBoOwp9CgpzdGF0aWMgRmNDaGFyOCAqKgpGY0NvbmZpZ1NhdmVBdHRyIChjb25zdCBYTUxfQ2hhciAqKmF0dHIpCnsKICAgIGludAkJbjsKICAgIGludAkJc2xlbjsKICAgIGludAkJaTsKICAgIEZjQ2hhcjgJKipuZXc7CiAgICBGY0NoYXI4CSpzOwoKICAgIGlmICghYXR0cikKCXJldHVybiAwOwogICAgc2xlbiA9IDA7CiAgICBmb3IgKGkgPSAwOyBhdHRyW2ldOyBpKyspCglzbGVuICs9IHN0cmxlbiAoYXR0cltpXSkgKyAxOwogICAgbiA9IGk7CiAgICBuZXcgPSBtYWxsb2MgKChpICsgMSkgKiBzaXplb2YgKEZjQ2hhcjggKikgKyBzbGVuKTsKICAgIGlmICghbmV3KQoJcmV0dXJuIDA7CiAgICBGY01lbUFsbG9jIChGQ19NRU1fQVRUUiwgMSk7ICAgIC8qIHNpemUgaXMgdG9vIGV4cGVuc2l2ZSAqLwogICAgcyA9IChGY0NoYXI4ICopIChuZXcgKyAoaSArIDEpKTsKICAgIGZvciAoaSA9IDA7IGF0dHJbaV07IGkrKykKICAgIHsKCW5ld1tpXSA9IHM7CglzdHJjcHkgKChjaGFyICopIHMsIChjaGFyICopIGF0dHJbaV0pOwoJcyArPSBzdHJsZW4gKChjaGFyICopIHMpICsgMTsKICAgIH0KICAgIG5ld1tpXSA9IDA7CiAgICByZXR1cm4gbmV3Owp9CgpzdGF0aWMgRmNCb29sCkZjUFN0YWNrUHVzaCAoRmNDb25maWdQYXJzZSAqcGFyc2UsIEZjRWxlbWVudCBlbGVtZW50LCBjb25zdCBYTUxfQ2hhciAqKmF0dHIpCnsKICAgIEZjUFN0YWNrICAgKm5ldyA9IG1hbGxvYyAoc2l6ZW9mIChGY1BTdGFjaykpOwoKICAgIGlmICghbmV3KQoJcmV0dXJuIEZjRmFsc2U7CiAgICBGY01lbUFsbG9jIChGQ19NRU1fUFNUQUNLLCBzaXplb2YgKEZjUFN0YWNrKSk7CiAgICBuZXctPnByZXYgPSBwYXJzZS0+cHN0YWNrOwogICAgbmV3LT5lbGVtZW50ID0gZWxlbWVudDsKICAgIGlmIChhdHRyKQogICAgewoJbmV3LT5hdHRyID0gRmNDb25maWdTYXZlQXR0ciAoYXR0cik7CglpZiAoIW5ldy0+YXR0cikKCSAgICBGY0NvbmZpZ01lc3NhZ2UgKHBhcnNlLCBGY1NldmVyZUVycm9yLCAib3V0IG9mIG1lbW9yeSIpOwogICAgfQogICAgZWxzZQoJbmV3LT5hdHRyID0gMDsKICAgIEZjU3RyQnVmSW5pdCAoJm5ldy0+c3RyLCAwLCAwKTsKICAgIHBhcnNlLT5wc3RhY2sgPSBuZXc7CiAgICByZXR1cm4gRmNUcnVlOwp9CgpzdGF0aWMgRmNCb29sCkZjUFN0YWNrUG9wIChGY0NvbmZpZ1BhcnNlICpwYXJzZSkKewogICAgRmNQU3RhY2sgICAqb2xkOwogICAgCiAgICBpZiAoIXBhcnNlLT5wc3RhY2spIAogICAgewoJRmNDb25maWdNZXNzYWdlIChwYXJzZSwgRmNTZXZlcmVFcnJvciwgIm1pc21hdGNoaW5nIGVsZW1lbnQiKTsKCXJldHVybiBGY0ZhbHNlOwogICAgfQogICAgRmNWU3RhY2tDbGVhciAocGFyc2UpOwogICAgb2xkID0gcGFyc2UtPnBzdGFjazsKICAgIHBhcnNlLT5wc3RhY2sgPSBvbGQtPnByZXY7CiAgICBGY1N0ckJ1ZkRlc3Ryb3kgKCZvbGQtPnN0cik7CiAgICBpZiAob2xkLT5hdHRyKQogICAgewoJRmNNZW1GcmVlIChGQ19NRU1fQVRUUiwgMSk7IC8qIHNpemUgaXMgdG8gZXhwZW5zaXZlICovCglmcmVlIChvbGQtPmF0dHIpOwogICAgfQogICAgRmNNZW1GcmVlIChGQ19NRU1fUFNUQUNLLCBzaXplb2YgKEZjUFN0YWNrKSk7CiAgICBmcmVlIChvbGQpOwogICAgcmV0dXJuIEZjVHJ1ZTsKfQoKc3RhdGljIEZjQm9vbApGY0NvbmZpZ0luaXQgKEZjQ29uZmlnUGFyc2UgKnBhcnNlLCBjb25zdCBGY0NoYXI4ICpuYW1lLCBGY0NvbmZpZyAqY29uZmlnLCBYTUxfUGFyc2VyIHBhcnNlcikKewogICAgcGFyc2UtPnBzdGFjayA9IDA7CiAgICBwYXJzZS0+dnN0YWNrID0gMDsKICAgIHBhcnNlLT5lcnJvciA9IEZjRmFsc2U7CiAgICBwYXJzZS0+bmFtZSA9IG5hbWU7CiAgICBwYXJzZS0+Y29uZmlnID0gY29uZmlnOwogICAgcGFyc2UtPnBhcnNlciA9IHBhcnNlcjsKICAgIHJldHVybiBGY1RydWU7Cn0KCnN0YXRpYyB2b2lkCkZjQ29uZmlnQ2xlYW51cCAoRmNDb25maWdQYXJzZQkqcGFyc2UpCnsKICAgIHdoaWxlIChwYXJzZS0+cHN0YWNrKQoJRmNQU3RhY2tQb3AgKHBhcnNlKTsKfQoKc3RhdGljIGNvbnN0IEZjQ2hhcjggKgpGY0NvbmZpZ0dldEF0dHJpYnV0ZSAoRmNDb25maWdQYXJzZSAqcGFyc2UsIGNoYXIgKmF0dHIpCnsKICAgIEZjQ2hhcjggKiphdHRyczsKICAgIGlmICghcGFyc2UtPnBzdGFjaykKCXJldHVybiAwOwoKICAgIGF0dHJzID0gcGFyc2UtPnBzdGFjay0+YXR0cjsKICAgIHdoaWxlICgqYXR0cnMpCiAgICB7CglpZiAoIXN0cmNtcCAoKGNoYXIgKikgKmF0dHJzLCBhdHRyKSkKCSAgICByZXR1cm4gYXR0cnNbMV07CglhdHRycyArPSAyOwogICAgfQogICAgcmV0dXJuIDA7Cn0KCnN0YXRpYyB2b2lkCkZjU3RhcnRFbGVtZW50KHZvaWQgKnVzZXJEYXRhLCBjb25zdCBYTUxfQ2hhciAqbmFtZSwgY29uc3QgWE1MX0NoYXIgKiphdHRyKQp7CiAgICBGY0NvbmZpZ1BhcnNlICAgKnBhcnNlID0gdXNlckRhdGE7CiAgICBGY0VsZW1lbnQJICAgIGVsZW1lbnQ7CiAgICAKICAgIGVsZW1lbnQgPSBGY0VsZW1lbnRNYXAgKG5hbWUpOwogICAgaWYgKGVsZW1lbnQgPT0gRmNFbGVtZW50VW5rbm93bikKCUZjQ29uZmlnTWVzc2FnZSAocGFyc2UsIEZjU2V2ZXJlV2FybmluZywgInVua25vd24gZWxlbWVudCBcIiVzXCIiLCBuYW1lKTsKICAgIAogICAgaWYgKCFGY1BTdGFja1B1c2ggKHBhcnNlLCBlbGVtZW50LCBhdHRyKSkKICAgIHsKCUZjQ29uZmlnTWVzc2FnZSAocGFyc2UsIEZjU2V2ZXJlRXJyb3IsICJvdXQgb2YgbWVtb3J5Iik7CglyZXR1cm47CiAgICB9CiAgICByZXR1cm47Cn0KCnN0YXRpYyB2b2lkCkZjUGFyc2VCbGFuayAoRmNDb25maWdQYXJzZSAqcGFyc2UpCnsKICAgIGludAkgICAgbiA9IEZjVlN0YWNrRWxlbWVudHMgKHBhcnNlKTsKICAgIHdoaWxlIChuLS0gPiAwKQogICAgewoJRmNWU3RhY2sgICAgKnYgPSBGY1ZTdGFja0ZldGNoIChwYXJzZSwgbik7CglpZiAodi0+dGFnICE9IEZjVlN0YWNrSW50ZWdlcikKCSAgICBGY0NvbmZpZ01lc3NhZ2UgKHBhcnNlLCBGY1NldmVyZUVycm9yLCAibm9uLWludGVnZXIgYmxhbmsiKTsKCWVsc2UKCXsKCSAgICBpZiAoIXBhcnNlLT5jb25maWctPmJsYW5rcykKCSAgICB7CgkJcGFyc2UtPmNvbmZpZy0+YmxhbmtzID0gRmNCbGFua3NDcmVhdGUgKCk7CgkJaWYgKCFwYXJzZS0+Y29uZmlnLT5ibGFua3MpCgkJewoJCSAgICBGY0NvbmZpZ01lc3NhZ2UgKHBhcnNlLCBGY1NldmVyZUVycm9yLCAib3V0IG9mIG1lbW9yeSIpOwoJCSAgICBicmVhazsKCQl9CgkgICAgfQoJICAgIGlmICghRmNCbGFua3NBZGQgKHBhcnNlLT5jb25maWctPmJsYW5rcywgdi0+dS5pbnRlZ2VyKSkKCSAgICB7CgkJRmNDb25maWdNZXNzYWdlIChwYXJzZSwgRmNTZXZlcmVFcnJvciwgIm91dCBvZiBtZW1vcnkiKTsKCQlicmVhazsKCSAgICB9Cgl9CiAgICB9Cn0KCnN0YXRpYyB2b2lkCkZjUGFyc2VSZXNjYW4gKEZjQ29uZmlnUGFyc2UgKnBhcnNlKQp7CiAgICBpbnQJICAgIG4gPSBGY1ZTdGFja0VsZW1lbnRzIChwYXJzZSk7CiAgICB3aGlsZSAobi0tID4gMCkKICAgIHsKCUZjVlN0YWNrICAgICp2ID0gRmNWU3RhY2tGZXRjaCAocGFyc2UsIG4pOwoJaWYgKHYtPnRhZyAhPSBGY1ZTdGFja0ludGVnZXIpCgkgICAgRmNDb25maWdNZXNzYWdlIChwYXJzZSwgRmNTZXZlcmVXYXJuaW5nLCAibm9uLWludGVnZXIgcmVzY2FuIik7CgllbHNlCgkgICAgcGFyc2UtPmNvbmZpZy0+cmVzY2FuSW50ZXJ2YWwgPSB2LT51LmludGVnZXI7CiAgICB9Cn0KCnN0YXRpYyB2b2lkCkZjUGFyc2VJbnQgKEZjQ29uZmlnUGFyc2UgKnBhcnNlKQp7CiAgICBGY0NoYXI4ICpzLCAqZW5kOwogICAgaW50CSAgICBsOwogICAgCiAgICBpZiAoIXBhcnNlLT5wc3RhY2spCglyZXR1cm47CiAgICBzID0gRmNTdHJCdWZEb25lICgmcGFyc2UtPnBzdGFjay0+c3RyKTsKICAgIGlmICghcykKICAgIHsKCUZjQ29uZmlnTWVzc2FnZSAocGFyc2UsIEZjU2V2ZXJlRXJyb3IsICJvdXQgb2YgbWVtb3J5Iik7CglyZXR1cm47CiAgICB9CiAgICBlbmQgPSAwOwogICAgbCA9IChpbnQpIHN0cnRvbCAoKGNoYXIgKikgcywgKGNoYXIgKiopJmVuZCwgMCk7CiAgICBpZiAoZW5kICE9IHMgKyBzdHJsZW4gKChjaGFyICopIHMpKQoJRmNDb25maWdNZXNzYWdlIChwYXJzZSwgRmNTZXZlcmVFcnJvciwgIlwiJXNcIjogbm90IGEgdmFsaWQgaW50ZWdlciIsIHMpOwogICAgZWxzZQoJRmNWU3RhY2tQdXNoSW50ZWdlciAocGFyc2UsIGwpOwogICAgRmNTdHJGcmVlIChzKTsKfQoKLyoKICogaWRlYSBjb3BpZWQgZnJvbSBnbGliIGdfYXNjaWlfc3RydG9kIHdpdGggCiAqIHBlcm1pc3Npb24gb2YgdGhlIGF1dGhvciAoQWxleGFuZGVyIExhcnNzb24pIAogKi8KCiNpbmNsdWRlIDxsb2NhbGUuaD4KCnN0YXRpYyBkb3VibGUgCkZjU3RydG9kIChjaGFyICpzLCBjaGFyICoqZW5kKQp7CiAgICBzdHJ1Y3QgbGNvbnYgICAgKmxvY2FsZV9kYXRhOwogICAgY2hhcgkgICAgKmRvdDsKICAgIGRvdWJsZQkgICAgdjsKCiAgICAvKgogICAgICogSGF2ZSB0byBzd2FwIHRoZSBkZWNpbWFsIHBvaW50IHRvIG1hdGNoIHRoZSBjdXJyZW50IGxvY2FsZQogICAgICogaWYgdGhhdCBsb2NhbGUgZG9lc24ndCB1c2UgMHgyZQogICAgICovCiAgICBpZiAoKGRvdCA9IHN0cmNociAocywgMHgyZSkpICYmCgkobG9jYWxlX2RhdGEgPSBsb2NhbGVjb252ICgpKSAmJgoJKGxvY2FsZV9kYXRhLT5kZWNpbWFsX3BvaW50WzBdICE9IDB4MmUgfHwKCSBsb2NhbGVfZGF0YS0+ZGVjaW1hbF9wb2ludFsxXSAhPSAwKSkKICAgIHsKCWNoYXIJYnVmWzEyOF07CglpbnQJc2xlbiA9IHN0cmxlbiAocyk7CglpbnQJZGxlbiA9IHN0cmxlbiAobG9jYWxlX2RhdGEtPmRlY2ltYWxfcG9pbnQpOwoJCglpZiAoc2xlbiArIGRsZW4gPiBzaXplb2YgKGJ1ZikpCgl7CgkgICAgaWYgKGVuZCkKCQkqZW5kID0gczsKCSAgICB2ID0gMDsKCX0KCWVsc2UKCXsKCSAgICBjaGFyCSpidWZfZW5kOwoJICAgIC8qIG1hbnRpc3NhICovCgkgICAgc3RybmNweSAoYnVmLCBzLCBkb3QgLSBzKTsKCSAgICAvKiBkZWNpbWFsIHBvaW50ICovCgkgICAgc3RyY3B5IChidWYgKyAoZG90IC0gcyksIGxvY2FsZV9kYXRhLT5kZWNpbWFsX3BvaW50KTsKCSAgICAvKiByZXN0IG9mIG51bWJlciAqLwoJICAgIHN0cmNweSAoYnVmICsgKGRvdCAtIHMpICsgZGxlbiwgZG90ICsgMSk7CgkgICAgYnVmX2VuZCA9IDA7CgkgICAgdiA9IHN0cnRvZCAoYnVmLCAmYnVmX2VuZCk7CgkgICAgaWYgKGJ1Zl9lbmQpCgkJYnVmX2VuZCA9IHMgKyAoYnVmX2VuZCAtIGJ1Zik7CgkgICAgaWYgKGVuZCkKCQkqZW5kID0gYnVmX2VuZDsKCX0KICAgIH0KICAgIGVsc2UKCXYgPSBzdHJ0b2QgKHMsIGVuZCk7CiAgICByZXR1cm4gdjsKfQoKc3RhdGljIHZvaWQKRmNQYXJzZURvdWJsZSAoRmNDb25maWdQYXJzZSAqcGFyc2UpCnsKICAgIEZjQ2hhcjggKnMsICplbmQ7CiAgICBkb3VibGUgIGQ7CiAgICAKICAgIGlmICghcGFyc2UtPnBzdGFjaykKCXJldHVybjsKICAgIHMgPSBGY1N0ckJ1ZkRvbmUgKCZwYXJzZS0+cHN0YWNrLT5zdHIpOwogICAgaWYgKCFzKQogICAgewoJRmNDb25maWdNZXNzYWdlIChwYXJzZSwgRmNTZXZlcmVFcnJvciwgIm91dCBvZiBtZW1vcnkiKTsKCXJldHVybjsKICAgIH0KICAgIGVuZCA9IDA7CiAgICBkID0gRmNTdHJ0b2QgKChjaGFyICopIHMsIChjaGFyICoqKSZlbmQpOwogICAgaWYgKGVuZCAhPSBzICsgc3RybGVuICgoY2hhciAqKSBzKSkKCUZjQ29uZmlnTWVzc2FnZSAocGFyc2UsIEZjU2V2ZXJlRXJyb3IsICJcIiVzXCI6IG5vdCBhIHZhbGlkIGRvdWJsZSIsIHMpOwogICAgZWxzZQoJRmNWU3RhY2tQdXNoRG91YmxlIChwYXJzZSwgZCk7CiAgICBGY1N0ckZyZWUgKHMpOwp9CgpzdGF0aWMgdm9pZApGY1BhcnNlU3RyaW5nIChGY0NvbmZpZ1BhcnNlICpwYXJzZSwgRmNWU3RhY2tUYWcgdGFnKQp7CiAgICBGY0NoYXI4ICpzOwogICAgCiAgICBpZiAoIXBhcnNlLT5wc3RhY2spCglyZXR1cm47CiAgICBzID0gRmNTdHJCdWZEb25lICgmcGFyc2UtPnBzdGFjay0+c3RyKTsKICAgIGlmICghcykKICAgIHsKCUZjQ29uZmlnTWVzc2FnZSAocGFyc2UsIEZjU2V2ZXJlRXJyb3IsICJvdXQgb2YgbWVtb3J5Iik7CglyZXR1cm47CiAgICB9CiAgICBpZiAoIUZjVlN0YWNrUHVzaFN0cmluZyAocGFyc2UsIHRhZywgcykpCglGY1N0ckZyZWUgKHMpOwp9CgpzdGF0aWMgdm9pZApGY1BhcnNlTWF0cml4IChGY0NvbmZpZ1BhcnNlICpwYXJzZSkKewogICAgRmNWU3RhY2sJKnZzdGFjazsKICAgIGVudW0geyBtX2RvbmUsIG1feHgsIG1feHksIG1feXgsIG1feXkgfSBtYXRyaXhfc3RhdGUgPSBtX3l5OwogICAgRmNNYXRyaXgJbTsKICAgIAogICAgd2hpbGUgKCh2c3RhY2sgPSBGY1ZTdGFja1BvcCAocGFyc2UpKSkKICAgIHsKCWRvdWJsZQl2OwoJc3dpdGNoICh2c3RhY2stPnRhZykgewoJY2FzZSBGY1ZTdGFja0ludGVnZXI6CgkgICAgdiA9IHZzdGFjay0+dS5pbnRlZ2VyOwoJICAgIGJyZWFrOwoJY2FzZSBGY1ZTdGFja0RvdWJsZToKCSAgICB2ID0gdnN0YWNrLT51Ll9kb3VibGU7CgkgICAgYnJlYWs7CglkZWZhdWx0OgoJICAgIEZjQ29uZmlnTWVzc2FnZSAocGFyc2UsIEZjU2V2ZXJlRXJyb3IsICJub24tZG91YmxlIG1hdHJpeCBlbGVtZW50Iik7CgkgICAgdiA9IDEuMDsKCSAgICBicmVhazsKCX0KCXN3aXRjaCAobWF0cml4X3N0YXRlKSB7CgljYXNlIG1feHg6IG0ueHggPSB2OyBicmVhazsKCWNhc2UgbV94eTogbS54eSA9IHY7IGJyZWFrOwoJY2FzZSBtX3l4OiBtLnl4ID0gdjsgYnJlYWs7CgljYXNlIG1feXk6IG0ueXkgPSB2OyBicmVhazsKCWRlZmF1bHQ6IGJyZWFrOwoJfQoJRmNWU3RhY2tEZXN0cm95ICh2c3RhY2spOwoJbWF0cml4X3N0YXRlLS07CiAgICB9CiAgICBpZiAobWF0cml4X3N0YXRlICE9IG1fZG9uZSkKCUZjQ29uZmlnTWVzc2FnZSAocGFyc2UsIEZjU2V2ZXJlRXJyb3IsICJ3cm9uZyBudW1iZXIgb2YgbWF0cml4IGVsZW1lbnRzIik7CiAgICBlbHNlCglGY1ZTdGFja1B1c2hNYXRyaXggKHBhcnNlLCAmbSk7Cn0KCnN0YXRpYyBGY0Jvb2wKRmNDb25maWdMZXhCb29sIChjb25zdCBGY0NoYXI4ICpib29sKQp7CiAgICBpZiAoKmJvb2wgPT0gJ3QnIHx8ICpib29sID09ICdUJykKCXJldHVybiBGY1RydWU7CiAgICBpZiAoKmJvb2wgPT0gJ3knIHx8ICpib29sID09ICdZJykKCXJldHVybiBGY1RydWU7CiAgICBpZiAoKmJvb2wgPT0gJzEnKQoJcmV0dXJuIEZjVHJ1ZTsKICAgIHJldHVybiBGY0ZhbHNlOwp9CgpzdGF0aWMgdm9pZApGY1BhcnNlQm9vbCAoRmNDb25maWdQYXJzZSAqcGFyc2UpCnsKICAgIEZjQ2hhcjggKnM7CgogICAgaWYgKCFwYXJzZS0+cHN0YWNrKQoJcmV0dXJuOwogICAgcyA9IEZjU3RyQnVmRG9uZSAoJnBhcnNlLT5wc3RhY2stPnN0cik7CiAgICBpZiAoIXMpCiAgICB7CglGY0NvbmZpZ01lc3NhZ2UgKHBhcnNlLCBGY1NldmVyZUVycm9yLCAib3V0IG9mIG1lbW9yeSIpOwoJcmV0dXJuOwogICAgfQogICAgRmNWU3RhY2tQdXNoQm9vbCAocGFyc2UsIEZjQ29uZmlnTGV4Qm9vbCAocykpOwogICAgRmNTdHJGcmVlIChzKTsKfQoKc3RhdGljIHZvaWQKRmNQYXJzZUZhbWlsaWVzIChGY0NvbmZpZ1BhcnNlICpwYXJzZSwgRmNWU3RhY2tUYWcgdGFnKQp7CiAgICBGY1ZTdGFjawkqdnN0YWNrOwogICAgRmNFeHByCSpsZWZ0LCAqZXhwciA9IDAsICpuZXc7CgogICAgd2hpbGUgKCh2c3RhY2sgPSBGY1ZTdGFja1BvcCAocGFyc2UpKSkKICAgIHsKCWlmICh2c3RhY2stPnRhZyAhPSBGY1ZTdGFja0ZhbWlseSkKCXsKCSAgICBGY0NvbmZpZ01lc3NhZ2UgKHBhcnNlLCBGY1NldmVyZVdhcm5pbmcsICJub24tZmFtaWx5Iik7CgkgICAgRmNWU3RhY2tEZXN0cm95ICh2c3RhY2spOwoJICAgIGNvbnRpbnVlOwoJfQoJbGVmdCA9IHZzdGFjay0+dS5leHByOwoJdnN0YWNrLT50YWcgPSBGY1ZTdGFja05vbmU7CglGY1ZTdGFja0Rlc3Ryb3kgKHZzdGFjayk7CglpZiAoZXhwcikKCXsKCSAgICBuZXcgPSBGY0V4cHJDcmVhdGVPcCAobGVmdCwgRmNPcENvbW1hLCBleHByKTsKCSAgICBpZiAoIW5ldykKCSAgICB7CgkJRmNDb25maWdNZXNzYWdlIChwYXJzZSwgRmNTZXZlcmVFcnJvciwgIm91dCBvZiBtZW1vcnkiKTsKCQlGY0V4cHJEZXN0cm95IChsZWZ0KTsKCQlGY0V4cHJEZXN0cm95IChleHByKTsKCQlicmVhazsKCSAgICB9CgkgICAgZXhwciA9IG5ldzsKCX0KCWVsc2UKCSAgICBleHByID0gbGVmdDsKICAgIH0KICAgIGlmIChleHByKQogICAgewoJaWYgKCFGY1ZTdGFja1B1c2hFeHByIChwYXJzZSwgdGFnLCBleHByKSkKCXsKCSAgICBGY0NvbmZpZ01lc3NhZ2UgKHBhcnNlLCBGY1NldmVyZUVycm9yLCAib3V0IG9mIG1lbW9yeSIpOwoJICAgIGlmIChleHByKQoJCUZjRXhwckRlc3Ryb3kgKGV4cHIpOwoJfQogICAgfQp9CgpzdGF0aWMgdm9pZApGY1BhcnNlRmFtaWx5IChGY0NvbmZpZ1BhcnNlICpwYXJzZSkKewogICAgRmNDaGFyOCAqczsKICAgIEZjRXhwciAgKmV4cHI7CgogICAgaWYgKCFwYXJzZS0+cHN0YWNrKQoJcmV0dXJuOwogICAgcyA9IEZjU3RyQnVmRG9uZSAoJnBhcnNlLT5wc3RhY2stPnN0cik7CiAgICBpZiAoIXMpCiAgICB7CglGY0NvbmZpZ01lc3NhZ2UgKHBhcnNlLCBGY1NldmVyZUVycm9yLCAib3V0IG9mIG1lbW9yeSIpOwoJcmV0dXJuOwogICAgfQogICAgZXhwciA9IEZjRXhwckNyZWF0ZVN0cmluZyAocyk7CiAgICBGY1N0ckZyZWUgKHMpOwogICAgaWYgKGV4cHIpCglGY1ZTdGFja1B1c2hFeHByIChwYXJzZSwgRmNWU3RhY2tGYW1pbHksIGV4cHIpOwp9CgpzdGF0aWMgdm9pZApGY1BhcnNlQWxpYXMgKEZjQ29uZmlnUGFyc2UgKnBhcnNlKQp7CiAgICBGY0V4cHIJKmZhbWlseSA9IDAsICphY2NlcHQgPSAwLCAqcHJlZmVyID0gMCwgKmRlZiA9IDAsICpuZXcgPSAwOwogICAgRmNFZGl0CSplZGl0ID0gMCwgKm5leHQ7CiAgICBGY1ZTdGFjawkqdnN0YWNrOwogICAgRmNUZXN0CSp0ZXN0OwoKICAgIHdoaWxlICgodnN0YWNrID0gRmNWU3RhY2tQb3AgKHBhcnNlKSkpIAogICAgewoJc3dpdGNoICh2c3RhY2stPnRhZykgewoJY2FzZSBGY1ZTdGFja0ZhbWlseToKCSAgICBpZiAoZmFtaWx5KQoJICAgIHsKCQluZXcgPSBGY0V4cHJDcmVhdGVPcCAodnN0YWNrLT51LmV4cHIsIEZjT3BDb21tYSwgZmFtaWx5KTsKCQlpZiAoIW5ldykKCQkgICAgRmNDb25maWdNZXNzYWdlIChwYXJzZSwgRmNTZXZlcmVFcnJvciwgIm91dCBvZiBtZW1vcnkiKTsKCQllbHNlCgkJICAgIGZhbWlseSA9IG5ldzsKCSAgICB9CgkgICAgZWxzZQoJCW5ldyA9IHZzdGFjay0+dS5leHByOwoJICAgIGlmIChuZXcpCgkgICAgewoJCWZhbWlseSA9IG5ldzsKCQl2c3RhY2stPnRhZyA9IEZjVlN0YWNrTm9uZTsKCSAgICB9CgkgICAgYnJlYWs7CgljYXNlIEZjVlN0YWNrUHJlZmVyOgoJICAgIGlmIChwcmVmZXIpCgkJRmNFeHByRGVzdHJveSAocHJlZmVyKTsKCSAgICBwcmVmZXIgPSB2c3RhY2stPnUuZXhwcjsKCSAgICB2c3RhY2stPnRhZyA9IEZjVlN0YWNrTm9uZTsKCSAgICBicmVhazsKCWNhc2UgRmNWU3RhY2tBY2NlcHQ6CgkgICAgaWYgKGFjY2VwdCkKCQlGY0V4cHJEZXN0cm95IChhY2NlcHQpOwoJICAgIGFjY2VwdCA9IHZzdGFjay0+dS5leHByOwoJICAgIHZzdGFjay0+dGFnID0gRmNWU3RhY2tOb25lOwoJICAgIGJyZWFrOwoJY2FzZSBGY1ZTdGFja0RlZmF1bHQ6CgkgICAgaWYgKGRlZikKCQlGY0V4cHJEZXN0cm95IChkZWYpOwoJICAgIGRlZiA9IHZzdGFjay0+dS5leHByOwoJICAgIHZzdGFjay0+dGFnID0gRmNWU3RhY2tOb25lOwoJICAgIGJyZWFrOwoJZGVmYXVsdDoKCSAgICBGY0NvbmZpZ01lc3NhZ2UgKHBhcnNlLCBGY1NldmVyZVdhcm5pbmcsICJiYWQgYWxpYXMiKTsKCSAgICBicmVhazsKCX0KCUZjVlN0YWNrRGVzdHJveSAodnN0YWNrKTsKICAgIH0KICAgIGlmICghZmFtaWx5KQogICAgewoJRmNDb25maWdNZXNzYWdlIChwYXJzZSwgRmNTZXZlcmVFcnJvciwgIm1pc3NpbmcgZmFtaWx5IGluIGFsaWFzIik7CglpZiAocHJlZmVyKQoJICAgIEZjRXhwckRlc3Ryb3kgKHByZWZlcik7CglpZiAoYWNjZXB0KQoJICAgIEZjRXhwckRlc3Ryb3kgKGFjY2VwdCk7CglpZiAoZGVmKQoJICAgIEZjRXhwckRlc3Ryb3kgKGRlZik7CglyZXR1cm47CiAgICB9CiAgICBpZiAocHJlZmVyKQogICAgewoJZWRpdCA9IEZjRWRpdENyZWF0ZSAoRmNDb25maWdTYXZlRmllbGQgKCJmYW1pbHkiKSwKCQkJICAgICBGY09wUHJlcGVuZCwKCQkJICAgICBwcmVmZXIsCgkJCSAgICAgRmNWYWx1ZUJpbmRpbmdXZWFrKTsKCWlmIChlZGl0KQoJICAgIGVkaXQtPm5leHQgPSAwOwoJZWxzZQoJICAgIEZjRXhwckRlc3Ryb3kgKHByZWZlcik7CiAgICB9CiAgICBpZiAoYWNjZXB0KQogICAgewoJbmV4dCA9IGVkaXQ7CgllZGl0ID0gRmNFZGl0Q3JlYXRlIChGY0NvbmZpZ1NhdmVGaWVsZCAoImZhbWlseSIpLAoJCQkgICAgIEZjT3BBcHBlbmQsCgkJCSAgICAgYWNjZXB0LAoJCQkgICAgIEZjVmFsdWVCaW5kaW5nV2Vhayk7CglpZiAoZWRpdCkKCSAgICBlZGl0LT5uZXh0ID0gbmV4dDsKCWVsc2UKCSAgICBGY0V4cHJEZXN0cm95IChhY2NlcHQpOwogICAgfQogICAgaWYgKGRlZikKICAgIHsKCW5leHQgPSBlZGl0OwoJZWRpdCA9IEZjRWRpdENyZWF0ZSAoRmNDb25maWdTYXZlRmllbGQgKCJmYW1pbHkiKSwKCQkJICAgICBGY09wQXBwZW5kTGFzdCwKCQkJICAgICBkZWYsCgkJCSAgICAgRmNWYWx1ZUJpbmRpbmdXZWFrKTsKCWlmIChlZGl0KQoJICAgIGVkaXQtPm5leHQgPSBuZXh0OwoJZWxzZQoJICAgIEZjRXhwckRlc3Ryb3kgKGRlZik7CiAgICB9CiAgICBpZiAoZWRpdCkKICAgIHsKCXRlc3QgPSBGY1Rlc3RDcmVhdGUgKEZjTWF0Y2hQYXR0ZXJuLAoJCQkgICAgIEZjUXVhbEFueSwKCQkJICAgICAoRmNDaGFyOCAqKSBGQ19GQU1JTFksCgkJCSAgICAgRmNPcEVxdWFsLAoJCQkgICAgIGZhbWlseSk7CglpZiAodGVzdCkKCSAgICBpZiAoIUZjQ29uZmlnQWRkRWRpdCAocGFyc2UtPmNvbmZpZywgdGVzdCwgZWRpdCwgRmNNYXRjaFBhdHRlcm4pKQoJCUZjVGVzdERlc3Ryb3kgKHRlc3QpOwogICAgfQogICAgZWxzZQoJRmNFeHByRGVzdHJveSAoZmFtaWx5KTsKfQoKc3RhdGljIEZjRXhwciAqCkZjUG9wRXhwciAoRmNDb25maWdQYXJzZSAqcGFyc2UpCnsKICAgIEZjVlN0YWNrCSp2c3RhY2sgPSBGY1ZTdGFja1BvcCAocGFyc2UpOwogICAgRmNFeHByCSpleHByID0gMDsKICAgIGlmICghdnN0YWNrKQoJcmV0dXJuIDA7CiAgICBzd2l0Y2ggKHZzdGFjay0+dGFnKSB7CiAgICBjYXNlIEZjVlN0YWNrTm9uZToKCWJyZWFrOwogICAgY2FzZSBGY1ZTdGFja1N0cmluZzoKICAgIGNhc2UgRmNWU3RhY2tGYW1pbHk6CglleHByID0gRmNFeHByQ3JlYXRlU3RyaW5nICh2c3RhY2stPnUuc3RyaW5nKTsKCWJyZWFrOwogICAgY2FzZSBGY1ZTdGFja0ZpZWxkOgoJZXhwciA9IEZjRXhwckNyZWF0ZUZpZWxkICgoY2hhciAqKSB2c3RhY2stPnUuc3RyaW5nKTsKCWJyZWFrOwogICAgY2FzZSBGY1ZTdGFja0NvbnN0YW50OgoJZXhwciA9IEZjRXhwckNyZWF0ZUNvbnN0ICh2c3RhY2stPnUuc3RyaW5nKTsKCWJyZWFrOwogICAgY2FzZSBGY1ZTdGFja1ByZWZlcjoKICAgIGNhc2UgRmNWU3RhY2tBY2NlcHQ6CiAgICBjYXNlIEZjVlN0YWNrRGVmYXVsdDoKCWV4cHIgPSB2c3RhY2stPnUuZXhwcjsKCXZzdGFjay0+dGFnID0gRmNWU3RhY2tOb25lOwoJYnJlYWs7CiAgICBjYXNlIEZjVlN0YWNrSW50ZWdlcjoKCWV4cHIgPSBGY0V4cHJDcmVhdGVJbnRlZ2VyICh2c3RhY2stPnUuaW50ZWdlcik7CglicmVhazsKICAgIGNhc2UgRmNWU3RhY2tEb3VibGU6CglleHByID0gRmNFeHByQ3JlYXRlRG91YmxlICh2c3RhY2stPnUuX2RvdWJsZSk7CglicmVhazsKICAgIGNhc2UgRmNWU3RhY2tNYXRyaXg6CglleHByID0gRmNFeHByQ3JlYXRlTWF0cml4ICh2c3RhY2stPnUubWF0cml4KTsKCWJyZWFrOwogICAgY2FzZSBGY1ZTdGFja0Jvb2w6CglleHByID0gRmNFeHByQ3JlYXRlQm9vbCAodnN0YWNrLT51LmJvb2wpOwoJYnJlYWs7CiAgICBjYXNlIEZjVlN0YWNrVGVzdDoKCWJyZWFrOwogICAgY2FzZSBGY1ZTdGFja0V4cHI6CglleHByID0gdnN0YWNrLT51LmV4cHI7Cgl2c3RhY2stPnRhZyA9IEZjVlN0YWNrTm9uZTsKCWJyZWFrOwogICAgY2FzZSBGY1ZTdGFja0VkaXQ6CglicmVhazsKICAgIH0KICAgIEZjVlN0YWNrRGVzdHJveSAodnN0YWNrKTsKICAgIHJldHVybiBleHByOwp9CgpzdGF0aWMgRmNFeHByICoKRmNQb3BFeHBycyAoRmNDb25maWdQYXJzZSAqcGFyc2UsIEZjT3Agb3ApCnsKICAgIEZjRXhwciAgKmxlZnQsICpleHByID0gMCwgKm5ldzsKCiAgICB3aGlsZSAoKGxlZnQgPSBGY1BvcEV4cHIgKHBhcnNlKSkpCiAgICB7CglpZiAoZXhwcikKCXsKCSAgICBuZXcgPSBGY0V4cHJDcmVhdGVPcCAobGVmdCwgb3AsIGV4cHIpOwoJICAgIGlmICghbmV3KQoJICAgIHsKCQlGY0NvbmZpZ01lc3NhZ2UgKHBhcnNlLCBGY1NldmVyZUVycm9yLCAib3V0IG9mIG1lbW9yeSIpOwoJCUZjRXhwckRlc3Ryb3kgKGxlZnQpOwoJCUZjRXhwckRlc3Ryb3kgKGV4cHIpOwoJCWJyZWFrOwoJICAgIH0KCSAgICBleHByID0gbmV3OwoJfQoJZWxzZQoJICAgIGV4cHIgPSBsZWZ0OwogICAgfQogICAgcmV0dXJuIGV4cHI7Cn0KCnN0YXRpYyB2b2lkCkZjUGFyc2VFeHByIChGY0NvbmZpZ1BhcnNlICpwYXJzZSwgRmNPcCBvcCkKewogICAgRmNFeHByICAqZXhwciA9IEZjUG9wRXhwcnMgKHBhcnNlLCBvcCk7CiAgICBpZiAoZXhwcikKCUZjVlN0YWNrUHVzaEV4cHIgKHBhcnNlLCBGY1ZTdGFja0V4cHIsIGV4cHIpOwp9CgpzdGF0aWMgdm9pZApGY1BhcnNlSW5jbHVkZSAoRmNDb25maWdQYXJzZSAqcGFyc2UpCnsKICAgIEZjQ2hhcjgJICAgICpzOwogICAgY29uc3QgRmNDaGFyOCAgICppOwogICAgRmNCb29sCSAgICBpZ25vcmVfbWlzc2luZyA9IEZjRmFsc2U7CiAgICAKICAgIHMgPSBGY1N0ckJ1ZkRvbmUgKCZwYXJzZS0+cHN0YWNrLT5zdHIpOwogICAgaWYgKCFzKQogICAgewoJRmNDb25maWdNZXNzYWdlIChwYXJzZSwgRmNTZXZlcmVFcnJvciwgIm91dCBvZiBtZW1vcnkiKTsKCXJldHVybjsKICAgIH0KICAgIGkgPSBGY0NvbmZpZ0dldEF0dHJpYnV0ZSAocGFyc2UsICJpZ25vcmVfbWlzc2luZyIpOwogICAgaWYgKGkgJiYgRmNDb25maWdMZXhCb29sICgoRmNDaGFyOCAqKSBpKSA9PSBGY1RydWUpCglpZ25vcmVfbWlzc2luZyA9IEZjVHJ1ZTsKICAgIGlmICghRmNDb25maWdQYXJzZUFuZExvYWQgKHBhcnNlLT5jb25maWcsIHMsICFpZ25vcmVfbWlzc2luZykpCglwYXJzZS0+ZXJyb3IgPSBGY1RydWU7CiAgICBGY1N0ckZyZWUgKHMpOwp9Cgp0eXBlZGVmIHN0cnVjdCBfRmNPcE1hcCB7CiAgICBjaGFyICAgICpuYW1lOwogICAgRmNPcCAgICBvcDsKfSBGY09wTWFwOwoKc3RhdGljIEZjT3AKRmNDb25maWdMZXhPcCAoY29uc3QgRmNDaGFyOCAqb3AsIGNvbnN0IEZjT3BNYXAJKm1hcCwgaW50IG5tYXApCnsKICAgIGludAlpOwoKICAgIGZvciAoaSA9IDA7IGkgPCBubWFwOyBpKyspCglpZiAoIXN0cmNtcCAoKGNoYXIgKikgb3AsIG1hcFtpXS5uYW1lKSkgCgkgICAgcmV0dXJuIG1hcFtpXS5vcDsKICAgIHJldHVybiBGY09wSW52YWxpZDsKfQoKc3RhdGljIGNvbnN0IEZjT3BNYXAgZmNDb21wYXJlT3BzW10gPSB7CiAgICB7ICJlcSIsCQlGY09wRXF1YWwJICAgIH0sCiAgICB7ICJub3RfZXEiLAkJRmNPcE5vdEVxdWFsCSAgICB9LAogICAgeyAibGVzcyIsCQlGY09wTGVzcwkgICAgfSwKICAgIHsgImxlc3NfZXEiLAlGY09wTGVzc0VxdWFsCSAgICB9LAogICAgeyAibW9yZSIsCQlGY09wTW9yZQkgICAgfSwKICAgIHsgIm1vcmVfZXEiLAlGY09wTW9yZUVxdWFsCSAgICB9LAogICAgeyAiY29udGFpbnMiLAlGY09wQ29udGFpbnMJICAgIH0sCiAgICB7ICJub3RfY29udGFpbnMiLAlGY09wTm90Q29udGFpbnMJICAgIH0KfTsKCiNkZWZpbmUgTlVNX0NPTVBBUkVfT1BTIChzaXplb2YgZmNDb21wYXJlT3BzIC8gc2l6ZW9mIGZjQ29tcGFyZU9wc1swXSkKCnN0YXRpYyBGY09wCkZjQ29uZmlnTGV4Q29tcGFyZSAoY29uc3QgRmNDaGFyOCAqY29tcGFyZSkKewogICAgcmV0dXJuIEZjQ29uZmlnTGV4T3AgKGNvbXBhcmUsIGZjQ29tcGFyZU9wcywgTlVNX0NPTVBBUkVfT1BTKTsKfQoKCnN0YXRpYyB2b2lkCkZjUGFyc2VUZXN0IChGY0NvbmZpZ1BhcnNlICpwYXJzZSkKewogICAgY29uc3QgRmNDaGFyOCAgICpraW5kX3N0cmluZzsKICAgIEZjTWF0Y2hLaW5kCSAgICBraW5kOwogICAgY29uc3QgRmNDaGFyOCAgICpxdWFsX3N0cmluZzsKICAgIEZjUXVhbAkgICAgcXVhbDsKICAgIGNvbnN0IEZjQ2hhcjggICAqbmFtZTsKICAgIGNvbnN0IEZjQ2hhcjggICAqY29tcGFyZV9zdHJpbmc7CiAgICBGY09wCSAgICBjb21wYXJlOwogICAgRmNFeHByCSAgICAqZXhwcjsKICAgIEZjVGVzdAkgICAgKnRlc3Q7CgogICAga2luZF9zdHJpbmcgPSBGY0NvbmZpZ0dldEF0dHJpYnV0ZSAocGFyc2UsICJ0YXJnZXQiKTsKICAgIGlmICgha2luZF9zdHJpbmcpCglraW5kID0gRmNNYXRjaERlZmF1bHQ7CiAgICBlbHNlCiAgICB7CglpZiAoIXN0cmNtcCAoKGNoYXIgKikga2luZF9zdHJpbmcsICJwYXR0ZXJuIikpCgkgICAga2luZCA9IEZjTWF0Y2hQYXR0ZXJuOwoJZWxzZSBpZiAoIXN0cmNtcCAoKGNoYXIgKikga2luZF9zdHJpbmcsICJmb250IikpCgkgICAga2luZCA9IEZjTWF0Y2hGb250OwoJZWxzZSBpZiAoIXN0cmNtcCAoKGNoYXIgKikga2luZF9zdHJpbmcsICJkZWZhdWx0IikpCgkgICAga2luZCA9IEZjTWF0Y2hEZWZhdWx0OwoJZWxzZQoJewoJICAgIEZjQ29uZmlnTWVzc2FnZSAocGFyc2UsIEZjU2V2ZXJlV2FybmluZywgImludmFsaWQgdGVzdCB0YXJnZXQgXCIlc1wiIiwga2luZF9zdHJpbmcpOwoJICAgIHJldHVybjsKCX0KICAgIH0KICAgIHF1YWxfc3RyaW5nID0gRmNDb25maWdHZXRBdHRyaWJ1dGUgKHBhcnNlLCAicXVhbCIpOwogICAgaWYgKCFxdWFsX3N0cmluZykKCXF1YWwgPSBGY1F1YWxBbnk7CiAgICBlbHNlCiAgICB7CglpZiAoIXN0cmNtcCAoKGNoYXIgKikgcXVhbF9zdHJpbmcsICJhbnkiKSkKCSAgICBxdWFsID0gRmNRdWFsQW55OwoJZWxzZSBpZiAoIXN0cmNtcCAoKGNoYXIgKikgcXVhbF9zdHJpbmcsICJhbGwiKSkKCSAgICBxdWFsID0gRmNRdWFsQWxsOwoJZWxzZSBpZiAoIXN0cmNtcCAoKGNoYXIgKikgcXVhbF9zdHJpbmcsICJmaXJzdCIpKQoJICAgIHF1YWwgPSBGY1F1YWxGaXJzdDsKCWVsc2UgaWYgKCFzdHJjbXAgKChjaGFyICopIHF1YWxfc3RyaW5nLCAibm90X2ZpcnN0IikpCgkgICAgcXVhbCA9IEZjUXVhbE5vdEZpcnN0OwoJZWxzZQoJewoJICAgIEZjQ29uZmlnTWVzc2FnZSAocGFyc2UsIEZjU2V2ZXJlV2FybmluZywgImludmFsaWQgdGVzdCBxdWFsIFwiJXNcIiIsIHF1YWxfc3RyaW5nKTsKCSAgICByZXR1cm47Cgl9CiAgICB9CiAgICBuYW1lID0gRmNDb25maWdHZXRBdHRyaWJ1dGUgKHBhcnNlLCAibmFtZSIpOwogICAgaWYgKCFuYW1lKQogICAgewoJRmNDb25maWdNZXNzYWdlIChwYXJzZSwgRmNTZXZlcmVXYXJuaW5nLCAibWlzc2luZyB0ZXN0IG5hbWUiKTsKCXJldHVybjsKICAgIH0KICAgIGNvbXBhcmVfc3RyaW5nID0gRmNDb25maWdHZXRBdHRyaWJ1dGUgKHBhcnNlLCAiY29tcGFyZSIpOwogICAgaWYgKCFjb21wYXJlX3N0cmluZykKCWNvbXBhcmUgPSBGY09wRXF1YWw7CiAgICBlbHNlCiAgICB7Cgljb21wYXJlID0gRmNDb25maWdMZXhDb21wYXJlIChjb21wYXJlX3N0cmluZyk7CglpZiAoY29tcGFyZSA9PSBGY09wSW52YWxpZCkKCXsKCSAgICBGY0NvbmZpZ01lc3NhZ2UgKHBhcnNlLCBGY1NldmVyZVdhcm5pbmcsICJpbnZhbGlkIHRlc3QgY29tcGFyZSBcIiVzXCIiLCBjb21wYXJlX3N0cmluZyk7CgkgICAgcmV0dXJuOwoJfQogICAgfQogICAgZXhwciA9IEZjUG9wRXhwcnMgKHBhcnNlLCBGY09wQ29tbWEpOwogICAgaWYgKCFleHByKQogICAgewoJRmNDb25maWdNZXNzYWdlIChwYXJzZSwgRmNTZXZlcmVXYXJuaW5nLCAibWlzc2luZyB0ZXN0IGV4cHJlc3Npb24iKTsKCXJldHVybjsKICAgIH0KICAgIHRlc3QgPSBGY1Rlc3RDcmVhdGUgKGtpbmQsIHF1YWwsIG5hbWUsIGNvbXBhcmUsIGV4cHIpOwogICAgaWYgKCF0ZXN0KQogICAgewoJRmNDb25maWdNZXNzYWdlIChwYXJzZSwgRmNTZXZlcmVFcnJvciwgIm91dCBvZiBtZW1vcnkiKTsKCXJldHVybjsKICAgIH0KICAgIEZjVlN0YWNrUHVzaFRlc3QgKHBhcnNlLCB0ZXN0KTsKfQoKc3RhdGljIGNvbnN0IEZjT3BNYXAgZmNNb2RlT3BzW10gPSB7CiAgICB7ICJhc3NpZ24iLAkJRmNPcEFzc2lnbgkgICAgfSwKICAgIHsgImFzc2lnbl9yZXBsYWNlIiwJRmNPcEFzc2lnblJlcGxhY2UgICB9LAogICAgeyAicHJlcGVuZCIsCUZjT3BQcmVwZW5kCSAgICB9LAogICAgeyAicHJlcGVuZF9maXJzdCIsCUZjT3BQcmVwZW5kRmlyc3QgICAgfSwKICAgIHsgImFwcGVuZCIsCQlGY09wQXBwZW5kCSAgICB9LAogICAgeyAiYXBwZW5kX2xhc3QiLAlGY09wQXBwZW5kTGFzdAkgICAgfSwKfTsKCiNkZWZpbmUgTlVNX01PREVfT1BTIChzaXplb2YgZmNNb2RlT3BzIC8gc2l6ZW9mIGZjTW9kZU9wc1swXSkKCnN0YXRpYyBGY09wCkZjQ29uZmlnTGV4TW9kZSAoY29uc3QgRmNDaGFyOCAqbW9kZSkKewogICAgcmV0dXJuIEZjQ29uZmlnTGV4T3AgKG1vZGUsIGZjTW9kZU9wcywgTlVNX01PREVfT1BTKTsKfQoKc3RhdGljIHZvaWQKRmNQYXJzZUVkaXQgKEZjQ29uZmlnUGFyc2UgKnBhcnNlKQp7CiAgICBjb25zdCBGY0NoYXI4ICAgKm5hbWU7CiAgICBjb25zdCBGY0NoYXI4ICAgKm1vZGVfc3RyaW5nOwogICAgY29uc3QgRmNDaGFyOCAgICpiaW5kaW5nX3N0cmluZzsKICAgIEZjT3AJICAgIG1vZGU7CiAgICBGY1ZhbHVlQmluZGluZyAgYmluZGluZzsKICAgIEZjRXhwcgkgICAgKmV4cHI7CiAgICBGY0VkaXQJICAgICplZGl0OwoKICAgIG5hbWUgPSBGY0NvbmZpZ0dldEF0dHJpYnV0ZSAocGFyc2UsICJuYW1lIik7CiAgICBpZiAoIW5hbWUpCiAgICB7CglGY0NvbmZpZ01lc3NhZ2UgKHBhcnNlLCBGY1NldmVyZVdhcm5pbmcsICJtaXNzaW5nIGVkaXQgbmFtZSIpOwoJcmV0dXJuOwogICAgfQogICAgbW9kZV9zdHJpbmcgPSBGY0NvbmZpZ0dldEF0dHJpYnV0ZSAocGFyc2UsICJtb2RlIik7CiAgICBpZiAoIW1vZGVfc3RyaW5nKQoJbW9kZSA9IEZjT3BBc3NpZ247CiAgICBlbHNlCiAgICB7Cgltb2RlID0gRmNDb25maWdMZXhNb2RlIChtb2RlX3N0cmluZyk7CglpZiAobW9kZSA9PSBGY09wSW52YWxpZCkKCXsKCSAgICBGY0NvbmZpZ01lc3NhZ2UgKHBhcnNlLCBGY1NldmVyZVdhcm5pbmcsICJpbnZhbGlkIGVkaXQgbW9kZSBcIiVzXCIiLCBtb2RlX3N0cmluZyk7CgkgICAgcmV0dXJuOwoJfQogICAgfQogICAgYmluZGluZ19zdHJpbmcgPSBGY0NvbmZpZ0dldEF0dHJpYnV0ZSAocGFyc2UsICJiaW5kaW5nIik7CiAgICBpZiAoIWJpbmRpbmdfc3RyaW5nKQoJYmluZGluZyA9IEZjVmFsdWVCaW5kaW5nV2VhazsKICAgIGVsc2UKICAgIHsKCWlmICghc3RyY21wICgoY2hhciAqKSBiaW5kaW5nX3N0cmluZywgIndlYWsiKSkKCSAgICBiaW5kaW5nID0gRmNWYWx1ZUJpbmRpbmdXZWFrOwoJZWxzZSBpZiAoIXN0cmNtcCAoKGNoYXIgKikgYmluZGluZ19zdHJpbmcsICJzdHJvbmciKSkKCSAgICBiaW5kaW5nID0gRmNWYWx1ZUJpbmRpbmdTdHJvbmc7CgllbHNlCgl7CgkgICAgRmNDb25maWdNZXNzYWdlIChwYXJzZSwgRmNTZXZlcmVXYXJuaW5nLCAiaW52YWxpZCBlZGl0IGJpbmRpbmcgXCIlc1wiIiwgYmluZGluZ19zdHJpbmcpOwoJICAgIHJldHVybjsKCX0KICAgIH0KICAgIGV4cHIgPSBGY1BvcEV4cHJzIChwYXJzZSwgRmNPcENvbW1hKTsKICAgIGVkaXQgPSBGY0VkaXRDcmVhdGUgKChjaGFyICopIEZjU3RyQ29weSAobmFtZSksIG1vZGUsIGV4cHIsIGJpbmRpbmcpOwogICAgaWYgKCFlZGl0KQogICAgewoJRmNDb25maWdNZXNzYWdlIChwYXJzZSwgRmNTZXZlcmVFcnJvciwgIm91dCBvZiBtZW1vcnkiKTsKCUZjRXhwckRlc3Ryb3kgKGV4cHIpOwoJcmV0dXJuOwogICAgfQogICAgaWYgKCFGY1ZTdGFja1B1c2hFZGl0IChwYXJzZSwgZWRpdCkpCglGY0VkaXREZXN0cm95IChlZGl0KTsKfQoKc3RhdGljIHZvaWQKRmNQYXJzZU1hdGNoIChGY0NvbmZpZ1BhcnNlICpwYXJzZSkKewogICAgY29uc3QgRmNDaGFyOCAgICpraW5kX25hbWU7CiAgICBGY01hdGNoS2luZAkgICAga2luZDsKICAgIEZjVGVzdAkgICAgKnRlc3QgPSAwOwogICAgRmNFZGl0CSAgICAqZWRpdCA9IDA7CiAgICBGY1ZTdGFjawkgICAgKnZzdGFjazsKCiAgICBraW5kX25hbWUgPSBGY0NvbmZpZ0dldEF0dHJpYnV0ZSAocGFyc2UsICJ0YXJnZXQiKTsKICAgIGlmICgha2luZF9uYW1lKQoJa2luZCA9IEZjTWF0Y2hQYXR0ZXJuOwogICAgZWxzZQogICAgewoJaWYgKCFzdHJjbXAgKChjaGFyICopIGtpbmRfbmFtZSwgInBhdHRlcm4iKSkKCSAgICBraW5kID0gRmNNYXRjaFBhdHRlcm47CgllbHNlIGlmICghc3RyY21wICgoY2hhciAqKSBraW5kX25hbWUsICJmb250IikpCgkgICAga2luZCA9IEZjTWF0Y2hGb250OwoJZWxzZQoJewoJICAgIEZjQ29uZmlnTWVzc2FnZSAocGFyc2UsIEZjU2V2ZXJlV2FybmluZywgImludmFsaWQgbWF0Y2ggdGFyZ2V0IFwiJXNcIiIsIGtpbmRfbmFtZSk7CgkgICAgcmV0dXJuOwoJfQogICAgfQogICAgd2hpbGUgKCh2c3RhY2sgPSBGY1ZTdGFja1BvcCAocGFyc2UpKSkKICAgIHsKCXN3aXRjaCAodnN0YWNrLT50YWcpIHsKCWNhc2UgRmNWU3RhY2tUZXN0OgoJICAgIHZzdGFjay0+dS50ZXN0LT5uZXh0ID0gdGVzdDsKCSAgICB0ZXN0ID0gdnN0YWNrLT51LnRlc3Q7CgkgICAgdnN0YWNrLT50YWcgPSBGY1ZTdGFja05vbmU7CgkgICAgYnJlYWs7CgljYXNlIEZjVlN0YWNrRWRpdDoKCSAgICB2c3RhY2stPnUuZWRpdC0+bmV4dCA9IGVkaXQ7CgkgICAgZWRpdCA9IHZzdGFjay0+dS5lZGl0OwoJICAgIHZzdGFjay0+dGFnID0gRmNWU3RhY2tOb25lOwoJICAgIGJyZWFrOwoJZGVmYXVsdDoKCSAgICBGY0NvbmZpZ01lc3NhZ2UgKHBhcnNlLCBGY1NldmVyZVdhcm5pbmcsICJpbnZhbGlkIG1hdGNoIGVsZW1lbnQiKTsKCSAgICBicmVhazsKCX0KCUZjVlN0YWNrRGVzdHJveSAodnN0YWNrKTsKICAgIH0KICAgIGlmICghRmNDb25maWdBZGRFZGl0IChwYXJzZS0+Y29uZmlnLCB0ZXN0LCBlZGl0LCBraW5kKSkKCUZjQ29uZmlnTWVzc2FnZSAocGFyc2UsIEZjU2V2ZXJlRXJyb3IsICJvdXQgb2YgbWVtb3J5Iik7Cn0KCnN0YXRpYyB2b2lkCkZjRW5kRWxlbWVudCh2b2lkICp1c2VyRGF0YSwgY29uc3QgWE1MX0NoYXIgKm5hbWUpCnsKICAgIEZjQ29uZmlnUGFyc2UgICAqcGFyc2UgPSB1c2VyRGF0YTsKICAgIEZjQ2hhcjgJICAgICpkYXRhOwogICAgCiAgICBpZiAoIXBhcnNlLT5wc3RhY2spCglyZXR1cm47CiAgICBzd2l0Y2ggKHBhcnNlLT5wc3RhY2stPmVsZW1lbnQpIHsKICAgIGNhc2UgRmNFbGVtZW50Tm9uZToKCWJyZWFrOwogICAgY2FzZSBGY0VsZW1lbnRGb250Y29uZmlnOgoJYnJlYWs7CiAgICBjYXNlIEZjRWxlbWVudERpcjoKCWRhdGEgPSBGY1N0ckJ1ZkRvbmUgKCZwYXJzZS0+cHN0YWNrLT5zdHIpOwoJaWYgKCFkYXRhKQoJewoJICAgIEZjQ29uZmlnTWVzc2FnZSAocGFyc2UsIEZjU2V2ZXJlRXJyb3IsICJvdXQgb2YgbWVtb3J5Iik7CgkgICAgYnJlYWs7Cgl9CglpZiAoIUZjQ29uZmlnQWRkRGlyIChwYXJzZS0+Y29uZmlnLCBkYXRhKSkKCSAgICBGY0NvbmZpZ01lc3NhZ2UgKHBhcnNlLCBGY1NldmVyZUVycm9yLCAib3V0IG9mIG1lbW9yeSIpOwoJRmNTdHJGcmVlIChkYXRhKTsKCWJyZWFrOwogICAgY2FzZSBGY0VsZW1lbnRDYWNoZToKCWRhdGEgPSBGY1N0ckJ1ZkRvbmUgKCZwYXJzZS0+cHN0YWNrLT5zdHIpOwoJaWYgKCFkYXRhKQoJewoJICAgIEZjQ29uZmlnTWVzc2FnZSAocGFyc2UsIEZjU2V2ZXJlRXJyb3IsICJvdXQgb2YgbWVtb3J5Iik7CgkgICAgYnJlYWs7Cgl9CglpZiAoIUZjQ29uZmlnU2V0Q2FjaGUgKHBhcnNlLT5jb25maWcsIGRhdGEpKQoJICAgIEZjQ29uZmlnTWVzc2FnZSAocGFyc2UsIEZjU2V2ZXJlRXJyb3IsICJvdXQgb2YgbWVtb3J5Iik7CglGY1N0ckZyZWUgKGRhdGEpOwoJYnJlYWs7CiAgICBjYXNlIEZjRWxlbWVudEluY2x1ZGU6CglGY1BhcnNlSW5jbHVkZSAocGFyc2UpOwoJYnJlYWs7CiAgICBjYXNlIEZjRWxlbWVudENvbmZpZzoKCWJyZWFrOwogICAgY2FzZSBGY0VsZW1lbnRNYXRjaDoKCUZjUGFyc2VNYXRjaCAocGFyc2UpOwoJYnJlYWs7CiAgICBjYXNlIEZjRWxlbWVudEFsaWFzOgoJRmNQYXJzZUFsaWFzIChwYXJzZSk7CglicmVhazsKCiAgICBjYXNlIEZjRWxlbWVudEJsYW5rOgoJRmNQYXJzZUJsYW5rIChwYXJzZSk7CglicmVhazsKICAgIGNhc2UgRmNFbGVtZW50UmVzY2FuOgoJRmNQYXJzZVJlc2NhbiAocGFyc2UpOwoJYnJlYWs7CgkKICAgIGNhc2UgRmNFbGVtZW50UHJlZmVyOgoJRmNQYXJzZUZhbWlsaWVzIChwYXJzZSwgRmNWU3RhY2tQcmVmZXIpOwoJYnJlYWs7CiAgICBjYXNlIEZjRWxlbWVudEFjY2VwdDoKCUZjUGFyc2VGYW1pbGllcyAocGFyc2UsIEZjVlN0YWNrQWNjZXB0KTsKCWJyZWFrOwogICAgY2FzZSBGY0VsZW1lbnREZWZhdWx0OgoJRmNQYXJzZUZhbWlsaWVzIChwYXJzZSwgRmNWU3RhY2tEZWZhdWx0KTsKCWJyZWFrOwogICAgY2FzZSBGY0VsZW1lbnRGYW1pbHk6CglGY1BhcnNlRmFtaWx5IChwYXJzZSk7CglicmVhazsKCiAgICBjYXNlIEZjRWxlbWVudFRlc3Q6CglGY1BhcnNlVGVzdCAocGFyc2UpOwoJYnJlYWs7CiAgICBjYXNlIEZjRWxlbWVudEVkaXQ6CglGY1BhcnNlRWRpdCAocGFyc2UpOwoJYnJlYWs7CgogICAgY2FzZSBGY0VsZW1lbnRJbnQ6CglGY1BhcnNlSW50IChwYXJzZSk7CglicmVhazsKICAgIGNhc2UgRmNFbGVtZW50RG91YmxlOgoJRmNQYXJzZURvdWJsZSAocGFyc2UpOwoJYnJlYWs7CiAgICBjYXNlIEZjRWxlbWVudFN0cmluZzoKCUZjUGFyc2VTdHJpbmcgKHBhcnNlLCBGY1ZTdGFja1N0cmluZyk7CglicmVhazsKICAgIGNhc2UgRmNFbGVtZW50TWF0cml4OgoJRmNQYXJzZU1hdHJpeCAocGFyc2UpOwoJYnJlYWs7CiAgICBjYXNlIEZjRWxlbWVudEJvb2w6CglGY1BhcnNlQm9vbCAocGFyc2UpOwoJYnJlYWs7CiAgICBjYXNlIEZjRWxlbWVudENoYXJzZXQ6Ci8qCUZjUGFyc2VDaGFyc2V0IChwYXJzZSk7ICovCglicmVhazsKCiAgICBjYXNlIEZjRWxlbWVudE5hbWU6CglGY1BhcnNlU3RyaW5nIChwYXJzZSwgRmNWU3RhY2tGaWVsZCk7CglicmVhazsKICAgIGNhc2UgRmNFbGVtZW50Q29uc3Q6CglGY1BhcnNlU3RyaW5nIChwYXJzZSwgRmNWU3RhY2tDb25zdGFudCk7CglicmVhazsKICAgIGNhc2UgRmNFbGVtZW50T3I6CglGY1BhcnNlRXhwciAocGFyc2UsIEZjT3BPcik7CglicmVhazsKICAgIGNhc2UgRmNFbGVtZW50QW5kOgoJRmNQYXJzZUV4cHIgKHBhcnNlLCBGY09wQW5kKTsKCWJyZWFrOwogICAgY2FzZSBGY0VsZW1lbnRFcToKCUZjUGFyc2VFeHByIChwYXJzZSwgRmNPcEVxdWFsKTsKCWJyZWFrOwogICAgY2FzZSBGY0VsZW1lbnROb3RFcToKCUZjUGFyc2VFeHByIChwYXJzZSwgRmNPcE5vdEVxdWFsKTsKCWJyZWFrOwogICAgY2FzZSBGY0VsZW1lbnRMZXNzOgoJRmNQYXJzZUV4cHIgKHBhcnNlLCBGY09wTGVzcyk7CglicmVhazsKICAgIGNhc2UgRmNFbGVtZW50TGVzc0VxOgoJRmNQYXJzZUV4cHIgKHBhcnNlLCBGY09wTGVzc0VxdWFsKTsKCWJyZWFrOwogICAgY2FzZSBGY0VsZW1lbnRNb3JlOgoJRmNQYXJzZUV4cHIgKHBhcnNlLCBGY09wTW9yZSk7CglicmVhazsKICAgIGNhc2UgRmNFbGVtZW50TW9yZUVxOgoJRmNQYXJzZUV4cHIgKHBhcnNlLCBGY09wTW9yZUVxdWFsKTsKCWJyZWFrOwogICAgY2FzZSBGY0VsZW1lbnRDb250YWluczoKCUZjUGFyc2VFeHByIChwYXJzZSwgRmNPcENvbnRhaW5zKTsKCWJyZWFrOwogICAgY2FzZSBGY0VsZW1lbnROb3RDb250YWluczoKCUZjUGFyc2VFeHByIChwYXJzZSwgRmNPcE5vdENvbnRhaW5zKTsKCWJyZWFrOwogICAgY2FzZSBGY0VsZW1lbnRQbHVzOgoJRmNQYXJzZUV4cHIgKHBhcnNlLCBGY09wUGx1cyk7CglicmVhazsKICAgIGNhc2UgRmNFbGVtZW50TWludXM6CglGY1BhcnNlRXhwciAocGFyc2UsIEZjT3BNaW51cyk7CglicmVhazsKICAgIGNhc2UgRmNFbGVtZW50VGltZXM6CglGY1BhcnNlRXhwciAocGFyc2UsIEZjT3BUaW1lcyk7CglicmVhazsKICAgIGNhc2UgRmNFbGVtZW50RGl2aWRlOgoJRmNQYXJzZUV4cHIgKHBhcnNlLCBGY09wRGl2aWRlKTsKCWJyZWFrOwogICAgY2FzZSBGY0VsZW1lbnROb3Q6CglGY1BhcnNlRXhwciAocGFyc2UsIEZjT3BOb3QpOwoJYnJlYWs7CiAgICBjYXNlIEZjRWxlbWVudElmOgoJRmNQYXJzZUV4cHIgKHBhcnNlLCBGY09wUXVlc3QpOwoJYnJlYWs7CiAgICBjYXNlIEZjRWxlbWVudFVua25vd246CglicmVhazsKICAgIH0KICAgICh2b2lkKSBGY1BTdGFja1BvcCAocGFyc2UpOwp9CgpzdGF0aWMgdm9pZApGY0NoYXJhY3RlckRhdGEgKHZvaWQgKnVzZXJEYXRhLCBjb25zdCBYTUxfQ2hhciAqcywgaW50IGxlbikKewogICAgRmNDb25maWdQYXJzZSAgICpwYXJzZSA9IHVzZXJEYXRhOwogICAgCiAgICBpZiAoIXBhcnNlLT5wc3RhY2spCglyZXR1cm47CiAgICBpZiAoIUZjU3RyQnVmRGF0YSAoJnBhcnNlLT5wc3RhY2stPnN0ciwgKEZjQ2hhcjggKikgcywgbGVuKSkKCUZjQ29uZmlnTWVzc2FnZSAocGFyc2UsIEZjU2V2ZXJlRXJyb3IsICJvdXQgb2YgbWVtb3J5Iik7Cn0KCnN0YXRpYyB2b2lkCkZjU3RhcnREb2N0eXBlRGVjbCAodm9pZAkgICAgKnVzZXJEYXRhLAoJCSAgICBjb25zdCBYTUxfQ2hhciAgKmRvY3R5cGVOYW1lLAoJCSAgICBjb25zdCBYTUxfQ2hhciAgKnN5c2lkLAoJCSAgICBjb25zdCBYTUxfQ2hhciAgKnB1YmlkLAoJCSAgICBpbnQJCSAgICBoYXNfaW50ZXJuYWxfc3Vic2V0KQp7CiAgICBGY0NvbmZpZ1BhcnNlICAgKnBhcnNlID0gdXNlckRhdGE7CgogICAgaWYgKHN0cmNtcCAoKGNoYXIgKikgZG9jdHlwZU5hbWUsICJmb250Y29uZmlnIikgIT0gMCkKCUZjQ29uZmlnTWVzc2FnZSAocGFyc2UsIEZjU2V2ZXJlRXJyb3IsICJpbnZhbGlkIGRvY3R5cGUgXCIlc1wiIiwgZG9jdHlwZU5hbWUpOwp9CgpzdGF0aWMgdm9pZApGY0VuZERvY3R5cGVEZWNsICh2b2lkICp1c2VyRGF0YSkKewp9CgpGY0Jvb2wKRmNDb25maWdQYXJzZUFuZExvYWQgKEZjQ29uZmlnCSAgICAqY29uZmlnLAoJCSAgICAgIGNvbnN0IEZjQ2hhcjggKm5hbWUsCgkJICAgICAgRmNCb29sCSAgICBjb21wbGFpbikKewoKICAgIFhNTF9QYXJzZXIJICAgIHA7CiAgICBGY0NoYXI4CSAgICAqZmlsZW5hbWU7CiAgICBGSUxFCSAgICAqZjsKICAgIGludAkJICAgIGxlbjsKICAgIHZvaWQJICAgICpidWY7CiAgICBGY0NvbmZpZ1BhcnNlICAgcGFyc2U7CiAgICBGY0Jvb2wJICAgIGVycm9yID0gRmNUcnVlOwogICAgCiAgICBmaWxlbmFtZSA9IEZjQ29uZmlnRmlsZW5hbWUgKG5hbWUpOwogICAgaWYgKCFmaWxlbmFtZSkKCWdvdG8gYmFpbDA7CiAgICAKICAgIGlmICghRmNTdHJTZXRBZGQgKGNvbmZpZy0+Y29uZmlnRmlsZXMsIGZpbGVuYW1lKSkKICAgIHsKCUZjU3RyRnJlZSAoZmlsZW5hbWUpOwoJZ290byBiYWlsMDsKICAgIH0KCiAgICBmID0gZm9wZW4gKChjaGFyICopIGZpbGVuYW1lLCAiciIpOwogICAgRmNTdHJGcmVlIChmaWxlbmFtZSk7CiAgICBpZiAoIWYpCglnb3RvIGJhaWwwOwogICAgCiAgICBwID0gWE1MX1BhcnNlckNyZWF0ZSAoIlVURi04Iik7CiAgICBpZiAoIXApCglnb3RvIGJhaWwxOwoKICAgIGlmICghRmNDb25maWdJbml0ICgmcGFyc2UsIG5hbWUsIGNvbmZpZywgcCkpCglnb3RvIGJhaWwyOwoKICAgIFhNTF9TZXRVc2VyRGF0YSAocCwgJnBhcnNlKTsKICAgIAogICAgWE1MX1NldERvY3R5cGVEZWNsSGFuZGxlciAocCwgRmNTdGFydERvY3R5cGVEZWNsLCBGY0VuZERvY3R5cGVEZWNsKTsKICAgIFhNTF9TZXRFbGVtZW50SGFuZGxlciAocCwgRmNTdGFydEVsZW1lbnQsIEZjRW5kRWxlbWVudCk7CiAgICBYTUxfU2V0Q2hhcmFjdGVyRGF0YUhhbmRsZXIgKHAsIEZjQ2hhcmFjdGVyRGF0YSk7CgkKICAgIGRvIHsKCWJ1ZiA9IFhNTF9HZXRCdWZmZXIgKHAsIEJVRlNJWik7CglpZiAoIWJ1ZikKCXsKCSAgICBGY0NvbmZpZ01lc3NhZ2UgKCZwYXJzZSwgRmNTZXZlcmVFcnJvciwgImNhbm5vdCBnZXQgcGFyc2UgYnVmZmVyIik7CgkgICAgZ290byBiYWlsMzsKCX0KCWxlbiA9IGZyZWFkIChidWYsIDEsIEJVRlNJWiwgZik7CglpZiAobGVuIDwgMCkKCXsKCSAgICBGY0NvbmZpZ01lc3NhZ2UgKCZwYXJzZSwgRmNTZXZlcmVFcnJvciwgImZhaWxlZCByZWFkaW5nIGNvbmZpZyBmaWxlIik7CgkgICAgZ290byBiYWlsMzsKCX0KCWlmICghWE1MX1BhcnNlQnVmZmVyIChwLCBsZW4sIGxlbiA9PSAwKSkKCXsKCSAgICBGY0NvbmZpZ01lc3NhZ2UgKCZwYXJzZSwgRmNTZXZlcmVFcnJvciwgIiVzIiwgCgkJCSAgIFhNTF9FcnJvclN0cmluZyAoWE1MX0dldEVycm9yQ29kZSAocCkpKTsKCSAgICBnb3RvIGJhaWwzOwoJfQogICAgfSB3aGlsZSAobGVuICE9IDApOwogICAgZXJyb3IgPSBwYXJzZS5lcnJvcjsKYmFpbDM6CiAgICBGY0NvbmZpZ0NsZWFudXAgKCZwYXJzZSk7CmJhaWwyOgogICAgWE1MX1BhcnNlckZyZWUgKHApOwpiYWlsMToKICAgIGZjbG9zZSAoZik7CmJhaWwwOgogICAgaWYgKGVycm9yICYmIGNvbXBsYWluKQogICAgewoJaWYgKG5hbWUpCgkgICAgRmNDb25maWdNZXNzYWdlICgwLCBGY1NldmVyZUVycm9yLCAiQ2Fubm90IGxvYWQgY29uZmlnIGZpbGUgXCIlc1wiIiwgbmFtZSk7CgllbHNlCgkgICAgRmNDb25maWdNZXNzYWdlICgwLCBGY1NldmVyZUVycm9yLCAiQ2Fubm90IGxvYWQgZGVmYXVsdCBjb25maWcgZmlsZSIpOwoJcmV0dXJuIEZjRmFsc2U7CiAgICB9CiAgICByZXR1cm4gRmNUcnVlOwp9Cg==