LyoKICogJFhGcmVlODY6ICQKICoKICogQ29weXJpZ2h0IKkgMjAwMiBLZWl0aCBQYWNrYXJkLCBtZW1iZXIgb2YgVGhlIFhGcmVlODYgUHJvamVjdCwgSW5jLgogKgogKiBQZXJtaXNzaW9uIHRvIHVzZSwgY29weSwgbW9kaWZ5LCBkaXN0cmlidXRlLCBhbmQgc2VsbCB0aGlzIHNvZnR3YXJlIGFuZCBpdHMKICogZG9jdW1lbnRhdGlvbiBmb3IgYW55IHB1cnBvc2UgaXMgaGVyZWJ5IGdyYW50ZWQgd2l0aG91dCBmZWUsIHByb3ZpZGVkIHRoYXQKICogdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UgYXBwZWFyIGluIGFsbCBjb3BpZXMgYW5kIHRoYXQgYm90aCB0aGF0CiAqIGNvcHlyaWdodCBub3RpY2UgYW5kIHRoaXMgcGVybWlzc2lvbiBub3RpY2UgYXBwZWFyIGluIHN1cHBvcnRpbmcKICogZG9jdW1lbnRhdGlvbiwgYW5kIHRoYXQgdGhlIG5hbWUgb2YgS2VpdGggUGFja2FyZCBub3QgYmUgdXNlZCBpbgogKiBhZHZlcnRpc2luZyBvciBwdWJsaWNpdHkgcGVydGFpbmluZyB0byBkaXN0cmlidXRpb24gb2YgdGhlIHNvZnR3YXJlIHdpdGhvdXQKICogc3BlY2lmaWMsIHdyaXR0ZW4gcHJpb3IgcGVybWlzc2lvbi4gIEtlaXRoIFBhY2thcmQgbWFrZXMgbm8KICogcmVwcmVzZW50YXRpb25zIGFib3V0IHRoZSBzdWl0YWJpbGl0eSBvZiB0aGlzIHNvZnR3YXJlIGZvciBhbnkgcHVycG9zZS4gIEl0CiAqIGlzIHByb3ZpZGVkICJhcyBpcyIgd2l0aG91dCBleHByZXNzIG9yIGltcGxpZWQgd2FycmFudHkuCiAqCiAqIEtFSVRIIFBBQ0tBUkQgRElTQ0xBSU1TIEFMTCBXQVJSQU5USUVTIFdJVEggUkVHQVJEIFRPIFRISVMgU09GVFdBUkUsCiAqIElOQ0xVRElORyBBTEwgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUywgSU4gTk8KICogRVZFTlQgU0hBTEwgS0VJVEggUEFDS0FSRCBCRSBMSUFCTEUgRk9SIEFOWSBTUEVDSUFMLCBJTkRJUkVDVCBPUgogKiBDT05TRVFVRU5USUFMIERBTUFHRVMgT1IgQU5ZIERBTUFHRVMgV0hBVFNPRVZFUiBSRVNVTFRJTkcgRlJPTSBMT1NTIE9GIFVTRSwKICogREFUQSBPUiBQUk9GSVRTLCBXSEVUSEVSIElOIEFOIEFDVElPTiBPRiBDT05UUkFDVCwgTkVHTElHRU5DRSBPUiBPVEhFUgogKiBUT1JUSU9VUyBBQ1RJT04sIEFSSVNJTkcgT1VUIE9GIE9SIElOIENPTk5FQ1RJT04gV0lUSCBUSEUgVVNFIE9SCiAqIFBFUkZPUk1BTkNFIE9GIFRISVMgU09GVFdBUkUuCiAqLwoKI2luY2x1ZGUgPHN0ZGFyZy5oPgojaW5jbHVkZSAiZmNpbnQuaCIKCnN0YXRpYyB4bWxQYXJzZXJJbnB1dFB0cgpGY0VudGl0eUxvYWRlciAoY29uc3QgY2hhciAqdXJsLCBjb25zdCBjaGFyICppZCwgeG1sUGFyc2VyQ3R4dFB0ciBjdHh0KQp7CiAgICB4bWxQYXJzZXJJbnB1dFB0cglyZXQ7CiAgICBjaGFyCQkqZmlsZTsKCiAgICBmaWxlID0gRmNDb25maWdGaWxlbmFtZSAodXJsKTsKICAgIGlmICghZmlsZSkKCXJldHVybiAwOwogICAgcmV0ID0geG1sTmV3SW5wdXRGcm9tRmlsZSAoY3R4dCwgZmlsZSk7CiAgICBmcmVlIChmaWxlKTsKICAgIHJldHVybiByZXQ7Cn0KCnhtbERvY1B0cgpGY0NvbmZpZ0xvYWQgKGNvbnN0IGNoYXIgKmZpbGUpCnsKICAgIHhtbERvY1B0cgkJICAgIGRvYzsKICAgIHhtbEV4dGVybmFsRW50aXR5TG9hZGVyIHByZXZpb3VzOwoKICAgIHByZXZpb3VzID0geG1sR2V0RXh0ZXJuYWxFbnRpdHlMb2FkZXIgKCk7CiAgICB4bWxTZXRFeHRlcm5hbEVudGl0eUxvYWRlciAoRmNFbnRpdHlMb2FkZXIpOwogICAgZG9jID0geG1sUGFyc2VGaWxlIChmaWxlKTsKICAgIHhtbFNldEV4dGVybmFsRW50aXR5TG9hZGVyIChwcmV2aW91cyk7CiAgICByZXR1cm4gZG9jOwp9CgojaWYgMAppbnQKRmNDb25maWdTYXZlIChjaGFyICpmaWxlLCB4bWxEb2NQdHIgZG9jKQp7Cn0KI2VuZGlmCgpGY1Rlc3QgKgpGY1Rlc3RDcmVhdGUgKEZjUXVhbCBxdWFsLCBjb25zdCBjaGFyICpmaWVsZCwgRmNPcCBjb21wYXJlLCBGY0V4cHIgKmV4cHIpCnsKICAgIEZjVGVzdAkqdGVzdCA9IChGY1Rlc3QgKikgbWFsbG9jIChzaXplb2YgKEZjVGVzdCkpOzsKCiAgICBpZiAodGVzdCkKICAgIHsKCXRlc3QtPm5leHQgPSAwOwoJdGVzdC0+cXVhbCA9IHF1YWw7Cgl0ZXN0LT5maWVsZCA9IEZjU3RyQ29weSAoZmllbGQpOwoJdGVzdC0+b3AgPSBjb21wYXJlOwoJdGVzdC0+ZXhwciA9IGV4cHI7CiAgICB9CiAgICByZXR1cm4gdGVzdDsKfQoKdm9pZApGY1Rlc3REZXN0cm95IChGY1Rlc3QgKnRlc3QpCnsKICAgIGlmICh0ZXN0LT5uZXh0KQoJRmNUZXN0RGVzdHJveSAodGVzdC0+bmV4dCk7CiAgICBGY0V4cHJEZXN0cm95ICh0ZXN0LT5leHByKTsKICAgIEZjU3RyRnJlZSAoKEZjQ2hhcjggKikgdGVzdC0+ZmllbGQpOwogICAgZnJlZSAodGVzdCk7Cn0KCkZjRXhwciAqCkZjRXhwckNyZWF0ZUludGVnZXIgKGludCBpKQp7CiAgICBGY0V4cHIgKmUgPSAoRmNFeHByICopIG1hbGxvYyAoc2l6ZW9mIChGY0V4cHIpKTsKCiAgICBpZiAoZSkKICAgIHsKCWUtPm9wID0gRmNPcEludGVnZXI7CgllLT51Lml2YWwgPSBpOwogICAgfQogICAgcmV0dXJuIGU7Cn0KCkZjRXhwciAqCkZjRXhwckNyZWF0ZURvdWJsZSAoZG91YmxlIGQpCnsKICAgIEZjRXhwciAqZSA9IChGY0V4cHIgKikgbWFsbG9jIChzaXplb2YgKEZjRXhwcikpOwoKICAgIGlmIChlKQogICAgewoJZS0+b3AgPSBGY09wRG91YmxlOwoJZS0+dS5kdmFsID0gZDsKICAgIH0KICAgIHJldHVybiBlOwp9CgpGY0V4cHIgKgpGY0V4cHJDcmVhdGVTdHJpbmcgKGNvbnN0IGNoYXIgKnMpCnsKICAgIEZjRXhwciAqZSA9IChGY0V4cHIgKikgbWFsbG9jIChzaXplb2YgKEZjRXhwcikpOwoKICAgIGlmIChlKQogICAgewoJZS0+b3AgPSBGY09wU3RyaW5nOwoJZS0+dS5zdmFsID0gRmNTdHJDb3B5IChzKTsKICAgIH0KICAgIHJldHVybiBlOwp9CgpGY0V4cHIgKgpGY0V4cHJDcmVhdGVNYXRyaXggKGNvbnN0IEZjTWF0cml4ICptKQp7CiAgICBGY0V4cHIgKmUgPSAoRmNFeHByICopIG1hbGxvYyAoc2l6ZW9mIChGY0V4cHIpKTsKCiAgICBpZiAoZSkKICAgIHsKCWUtPm9wID0gRmNPcE1hdHJpeDsKCWUtPnUubXZhbCA9IEZjTWF0cml4Q29weSAobSk7CiAgICB9CiAgICByZXR1cm4gZTsKfQoKRmNFeHByICoKRmNFeHByQ3JlYXRlQm9vbCAoRmNCb29sIGIpCnsKICAgIEZjRXhwciAqZSA9IChGY0V4cHIgKikgbWFsbG9jIChzaXplb2YgKEZjRXhwcikpOwoKICAgIGlmIChlKQogICAgewoJZS0+b3AgPSBGY09wQm9vbDsKCWUtPnUuYnZhbCA9IGI7CiAgICB9CiAgICByZXR1cm4gZTsKfQoKRmNFeHByICoKRmNFeHByQ3JlYXRlTmlsICh2b2lkKQp7CiAgICBGY0V4cHIgKmUgPSAoRmNFeHByICopIG1hbGxvYyAoc2l6ZW9mIChGY0V4cHIpKTsKCiAgICBpZiAoZSkKICAgIHsKCWUtPm9wID0gRmNPcE5pbDsKICAgIH0KICAgIHJldHVybiBlOwp9CgpGY0V4cHIgKgpGY0V4cHJDcmVhdGVGaWVsZCAoY29uc3QgY2hhciAqZmllbGQpCnsKICAgIEZjRXhwciAqZSA9IChGY0V4cHIgKikgbWFsbG9jIChzaXplb2YgKEZjRXhwcikpOwoKICAgIGlmIChlKQogICAgewoJZS0+b3AgPSBGY09wRmllbGQ7CgllLT51LmZpZWxkID0gRmNTdHJDb3B5IChmaWVsZCk7CiAgICB9CiAgICByZXR1cm4gZTsKfQoKRmNFeHByICoKRmNFeHByQ3JlYXRlQ29uc3QgKGNvbnN0IGNoYXIgKmNvbnN0YW50KQp7CiAgICBGY0V4cHIgKmUgPSAoRmNFeHByICopIG1hbGxvYyAoc2l6ZW9mIChGY0V4cHIpKTsKCiAgICBpZiAoZSkKICAgIHsKCWUtPm9wID0gRmNPcENvbnN0OwoJZS0+dS5jb25zdGFudCA9IEZjU3RyQ29weSAoY29uc3RhbnQpOwogICAgfQogICAgcmV0dXJuIGU7Cn0KCkZjRXhwciAqCkZjRXhwckNyZWF0ZU9wIChGY0V4cHIgKmxlZnQsIEZjT3Agb3AsIEZjRXhwciAqcmlnaHQpCnsKICAgIEZjRXhwciAqZSA9IChGY0V4cHIgKikgbWFsbG9jIChzaXplb2YgKEZjRXhwcikpOwoKICAgIGlmIChlKQogICAgewoJZS0+b3AgPSBvcDsKCWUtPnUudHJlZS5sZWZ0ID0gbGVmdDsKCWUtPnUudHJlZS5yaWdodCA9IHJpZ2h0OwogICAgfQogICAgcmV0dXJuIGU7Cn0KCnZvaWQKRmNFeHByRGVzdHJveSAoRmNFeHByICplKQp7CiAgICBzd2l0Y2ggKGUtPm9wKSB7CiAgICBjYXNlIEZjT3BJbnRlZ2VyOgoJYnJlYWs7CiAgICBjYXNlIEZjT3BEb3VibGU6CglicmVhazsKICAgIGNhc2UgRmNPcFN0cmluZzoKCUZjU3RyRnJlZSAoZS0+dS5zdmFsKTsKCWJyZWFrOwogICAgY2FzZSBGY09wTWF0cml4OgoJRmNNYXRyaXhGcmVlIChlLT51Lm12YWwpOwoJYnJlYWs7CiAgICBjYXNlIEZjT3BDaGFyU2V0OgoJRmNDaGFyU2V0RGVzdHJveSAoZS0+dS5jdmFsKTsKCWJyZWFrOwogICAgY2FzZSBGY09wQm9vbDoKCWJyZWFrOwogICAgY2FzZSBGY09wRmllbGQ6CglGY1N0ckZyZWUgKGUtPnUuZmllbGQpOwoJYnJlYWs7CiAgICBjYXNlIEZjT3BDb25zdDoKCUZjU3RyRnJlZSAoZS0+dS5jb25zdGFudCk7CglicmVhazsKICAgIGNhc2UgRmNPcEFzc2lnbjoKICAgIGNhc2UgRmNPcEFzc2lnblJlcGxhY2U6CiAgICBjYXNlIEZjT3BQcmVwZW5kOgogICAgY2FzZSBGY09wUHJlcGVuZEZpcnN0OgogICAgY2FzZSBGY09wQXBwZW5kOgogICAgY2FzZSBGY09wQXBwZW5kTGFzdDoKCWJyZWFrOwogICAgY2FzZSBGY09wT3I6CiAgICBjYXNlIEZjT3BBbmQ6CiAgICBjYXNlIEZjT3BFcXVhbDoKICAgIGNhc2UgRmNPcENvbnRhaW5zOgogICAgY2FzZSBGY09wTm90RXF1YWw6CiAgICBjYXNlIEZjT3BMZXNzOgogICAgY2FzZSBGY09wTGVzc0VxdWFsOgogICAgY2FzZSBGY09wTW9yZToKICAgIGNhc2UgRmNPcE1vcmVFcXVhbDoKICAgIGNhc2UgRmNPcFBsdXM6CiAgICBjYXNlIEZjT3BNaW51czoKICAgIGNhc2UgRmNPcFRpbWVzOgogICAgY2FzZSBGY09wRGl2aWRlOgogICAgY2FzZSBGY09wUXVlc3Q6CiAgICBjYXNlIEZjT3BDb21tYToKCUZjRXhwckRlc3Ryb3kgKGUtPnUudHJlZS5yaWdodCk7CgkvKiBmYWxsIHRocm91Z2ggKi8KICAgIGNhc2UgRmNPcE5vdDoKCUZjRXhwckRlc3Ryb3kgKGUtPnUudHJlZS5sZWZ0KTsKCWJyZWFrOwogICAgY2FzZSBGY09wTmlsOgogICAgY2FzZSBGY09wSW52YWxpZDoKCWJyZWFrOwogICAgfQogICAgZnJlZSAoZSk7Cn0KCkZjRWRpdCAqCkZjRWRpdENyZWF0ZSAoY29uc3QgY2hhciAqZmllbGQsIEZjT3Agb3AsIEZjRXhwciAqZXhwcikKewogICAgRmNFZGl0ICplID0gKEZjRWRpdCAqKSBtYWxsb2MgKHNpemVvZiAoRmNFZGl0KSk7CgogICAgaWYgKGUpCiAgICB7CgllLT5uZXh0ID0gMDsKCWUtPmZpZWxkID0gZmllbGQ7ICAgLyogYWxyZWFkeSBzYXZlZCBpbiBncmFtbWFyICovCgllLT5vcCA9IG9wOwoJZS0+ZXhwciA9IGV4cHI7CiAgICB9CiAgICByZXR1cm4gZTsKfQoKdm9pZApGY0VkaXREZXN0cm95IChGY0VkaXQgKmUpCnsKICAgIGlmIChlLT5uZXh0KQoJRmNFZGl0RGVzdHJveSAoZS0+bmV4dCk7CiAgICBGY1N0ckZyZWUgKChGY0NoYXI4ICopIGUtPmZpZWxkKTsKICAgIGlmIChlLT5leHByKQoJRmNFeHByRGVzdHJveSAoZS0+ZXhwcik7Cn0KCmNoYXIgKgpGY0NvbmZpZ1NhdmVGaWVsZCAoY29uc3QgY2hhciAqZmllbGQpCnsKICAgIHJldHVybiBGY1N0ckNvcHkgKGZpZWxkKTsKfQoKc3RhdGljIHZvaWQKRmNDb25maWdQYXJzZUVycm9yIChjaGFyICpmbXQsIC4uLikKewogICAgdmFfbGlzdAlhcmdzOwoKICAgIHZhX3N0YXJ0IChhcmdzLCBmbXQpOwogICAgZnByaW50ZiAoc3RkZXJyLCAiZm9udCBjb25maWd1cmF0aW9uIGVycm9yOiAiKTsKICAgIHZmcHJpbnRmIChzdGRlcnIsIGZtdCwgYXJncyk7CiAgICBmcHJpbnRmIChzdGRlcnIsICJcbiIpOwogICAgdmFfZW5kIChhcmdzKTsKfQoKc3RhdGljIGNoYXIgKgpGY0NvbmZpZ0NvbnRlbnQgKHhtbERvY1B0ciAgICBkb2MsCgkJIHhtbE5vZGVQdHIgICBub2RlKQp7CiAgICBjaGFyCSAgICAqY29udGVudDsKICAgIAogICAgY29udGVudCA9IHhtbE5vZGVMaXN0R2V0U3RyaW5nIChkb2MsIG5vZGUtPmNoaWxkcmVuLCAxKTsKICAgIGlmICghY29udGVudCkKICAgIHsKCUZjQ29uZmlnUGFyc2VFcnJvciAoIjwlcz4gbXVzdCBoYXZlIGNvbnRlbnQiLAoJCQkgICAgbm9kZS0+bmFtZSk7CglyZXR1cm4gRmNGYWxzZTsKICAgIH0KICAgIHJldHVybiBjb250ZW50Owp9CgpzdGF0aWMgY2hhciAqCkZjQ29uZmlnQXR0ciAoeG1sRG9jUHRyCSAgICBkb2MsCgkgICAgICB4bWxBdHRyUHRyICAgIGF0dHIpCnsKICAgIGNoYXIJICAgICpjb250ZW50OwogICAgCiAgICBjb250ZW50ID0geG1sTm9kZUxpc3RHZXRTdHJpbmcgKGRvYywgYXR0ci0+Y2hpbGRyZW4sIDEpOwogICAgaWYgKCFjb250ZW50KQogICAgewoJRmNDb25maWdQYXJzZUVycm9yICgiYXR0cmlidXRlICVzIG11c3QgaGF2ZSBhIHZhbHVlIiwKCQkJICAgIGF0dHItPm5hbWUpOwoJcmV0dXJuIEZjRmFsc2U7CiAgICB9CiAgICByZXR1cm4gY29udGVudDsKfQoKc3RhdGljIHN0cnVjdCB7CiAgICBjaGFyICAgICpuYW1lOwogICAgRmNPcCAgICBvcDsKfSBmY09wc1tdID0gewogICAgeyAiaW50IiwJCUZjT3BJbnRlZ2VyCSAgICB9LAogICAgeyAiZG91YmxlIiwJCUZjT3BEb3VibGUJICAgIH0sCiAgICB7ICJzdHJpbmciLAkJRmNPcFN0cmluZwkgICAgfSwKICAgIHsgIm1hdHJpeCIsCQlGY09wTWF0cml4CSAgICB9LAogICAgeyAiYm9vbCIsCQlGY09wQm9vbAkgICAgfSwKICAgIHsgImNoYXJzZXQiLAlGY09wQ2hhclNldAkgICAgfSwKICAgIHsgIm5hbWUiLAkJRmNPcEZpZWxkCSAgICB9LAogICAgeyAiY29uc3QiLAkJRmNPcENvbnN0CSAgICB9LAogICAgeyAiZmllbGQiLAkJRmNPcEZpZWxkCSAgICB9LAogICAgeyAiaWYiLAkJRmNPcFF1ZXN0CSAgICB9LAogICAgeyAib3IiLAkJRmNPcE9yCQkgICAgfSwKICAgIHsgImFuZCIsCQlGY09wQW5kCQkgICAgfSwKICAgIHsgImVxIiwJCUZjT3BFcXVhbAkgICAgfSwKICAgIHsgIm5vdF9lcSIsCQlGY09wTm90RXF1YWwJICAgIH0sCiAgICB7ICJsZXNzIiwJCUZjT3BMZXNzCSAgICB9LAogICAgeyAibGVzc19lcSIsCUZjT3BMZXNzRXF1YWwJICAgIH0sCiAgICB7ICJtb3JlIiwJCUZjT3BNb3JlCSAgICB9LAogICAgeyAibW9yZV9lcSIsCUZjT3BNb3JlRXF1YWwJICAgIH0sCiAgICB7ICJwbHVzIiwJCUZjT3BQbHVzCSAgICB9LAogICAgeyAibWludXMiLAkJRmNPcE1pbnVzCSAgICB9LAogICAgeyAidGltZXMiLAkJRmNPcFRpbWVzCSAgICB9LAogICAgeyAiZGl2aWRlIiwJCUZjT3BEaXZpZGUJICAgIH0sCiAgICB7ICJub3QiLAkJRmNPcE5vdAkJICAgIH0sCiAgICB7ICJhc3NpZ24iLAkJRmNPcEFzc2lnbgkgICAgfSwKICAgIHsgImFzc2lnbl9yZXBsYWNlIiwJRmNPcEFzc2lnblJlcGxhY2UgICB9LAogICAgeyAicHJlcGVuZCIsCUZjT3BQcmVwZW5kCSAgICB9LAogICAgeyAicHJlcGVuZF9maXJzdCIsCUZjT3BQcmVwZW5kRmlyc3QgICAgfSwKICAgIHsgImFwcGVuZCIsCQlGY09wQXBwZW5kCSAgICB9LAogICAgeyAiYXBwZW5kX2xhc3QiLAlGY09wQXBwZW5kTGFzdAkgICAgfSwKfTsKCiNkZWZpbmUgTlVNX09QUyAoc2l6ZW9mIGZjT3BzIC8gc2l6ZW9mIGZjT3BzWzBdKQoKc3RhdGljIEZjT3AKRmNDb25maWdMZXhPcCAoY29uc3QgY2hhciAqb3ApCnsKICAgIGludAlpOwoKICAgIGZvciAoaSA9IDA7IGkgPCBOVU1fT1BTOyBpKyspCglpZiAoIXN0cmNtcCAob3AsIGZjT3BzW2ldLm5hbWUpKSByZXR1cm4gZmNPcHNbaV0ub3A7CiAgICByZXR1cm4gRmNPcEludmFsaWQ7Cn0KCnN0YXRpYyBGY0Jvb2wKRmNDb25maWdMZXhCb29sIChjb25zdCBjaGFyICpib29sKQp7CiAgICBpZiAoKmJvb2wgPT0gJ3QnIHx8ICpib29sID09ICdUJykKCXJldHVybiBGY1RydWU7CiAgICBpZiAoKmJvb2wgPT0gJ3knIHx8ICpib29sID09ICdZJykKCXJldHVybiBGY1RydWU7CiAgICBpZiAoKmJvb2wgPT0gJzEnKQoJcmV0dXJuIEZjVHJ1ZTsKICAgIHJldHVybiBGY0ZhbHNlOwp9CgpzdGF0aWMgRmNCb29sCkZjQ29uZmlnUGFyc2VEaXIgKEZjQ29uZmlnCSpjb25maWcsCgkJICB4bWxEb2NQdHIJZG9jLAoJCSAgeG1sTm9kZVB0cglkaXIpCnsKICAgIGNoYXIgICAgKmNvbnRlbnQgPSBGY0NvbmZpZ0NvbnRlbnQgKGRvYywgZGlyKTsKCiAgICBpZiAoIWNvbnRlbnQpCglyZXR1cm4gRmNGYWxzZTsKICAgIHJldHVybiBGY0NvbmZpZ0FkZERpciAoY29uZmlnLCBjb250ZW50KTsKfQoKc3RhdGljIEZjQm9vbApGY0NvbmZpZ1BhcnNlQ2FjaGUgKEZjQ29uZmlnCSpjb25maWcsCgkJICAgIHhtbERvY1B0cglkb2MsCgkJICAgIHhtbE5vZGVQdHIJZGlyKQp7CiAgICBjaGFyICAgICpjb250ZW50ID0gRmNDb25maWdDb250ZW50IChkb2MsIGRpcik7CgogICAgaWYgKCFjb250ZW50KQoJcmV0dXJuIEZjRmFsc2U7CiAgICByZXR1cm4gRmNDb25maWdTZXRDYWNoZSAoY29uZmlnLCBjb250ZW50KTsKfQoKc3RhdGljIEZjQm9vbApGY0NvbmZpZ1BhcnNlSW5jbHVkZSAoRmNDb25maWcJICAgICpjb25maWcsCgkJICAgICAgeG1sRG9jUHRyCSAgICBkb2MsCgkJICAgICAgeG1sTm9kZVB0ciAgICBpbmMpCnsKICAgIGNoYXIJKmNvbnRlbnQgPSBGY0NvbmZpZ0NvbnRlbnQgKGRvYywgaW5jKTsKICAgIHhtbEF0dHIJKmF0dHI7CiAgICBGY0Jvb2wJY29tcGxhaW4gPSBGY1RydWU7CgogICAgaWYgKCFjb250ZW50KQoJcmV0dXJuIEZjRmFsc2U7CiAgICAKICAgIGZvciAoYXR0ciA9IGluYy0+cHJvcGVydGllczsgYXR0cjsgYXR0ciA9IGF0dHItPm5leHQpCiAgICB7CglpZiAoYXR0ci0+dHlwZSAhPSBYTUxfQVRUUklCVVRFX05PREUpCgkgICAgY29udGludWU7CglpZiAoIXN0cmNtcCAoYXR0ci0+bmFtZSwgImlnbm9yZV9taXNzaW5nIikpCgkgICAgY29tcGxhaW4gPSAhRmNDb25maWdMZXhCb29sIChGY0NvbmZpZ0F0dHIgKGRvYywgYXR0cikpOwogICAgfQogICAgcmV0dXJuIEZjQ29uZmlnUGFyc2VBbmRMb2FkIChjb25maWcsIGNvbnRlbnQsIGNvbXBsYWluKTsKfQoKc3RhdGljIEZjQm9vbApGY0NvbmZpZ1BhcnNlQmxhbmsgKEZjQ29uZmlnCSAgICAqY29uZmlnLAoJCSAgICB4bWxEb2NQdHIJICAgIGRvYywKCQkgICAgeG1sTm9kZVB0cgkgICAgYmxhbmspCnsKICAgIHhtbE5vZGUJKm5vZGU7CiAgICBGY0NoYXIzMgl1Y3M0OwoKICAgIGZvciAobm9kZSA9IGJsYW5rLT5jaGlsZHJlbjsgbm9kZTsgbm9kZSA9IG5vZGUtPm5leHQpCiAgICB7CglpZiAobm9kZS0+dHlwZSAhPSBYTUxfRUxFTUVOVF9OT0RFKQoJICAgIGNvbnRpbnVlOwoJaWYgKCFzdHJjbXAgKG5vZGUtPm5hbWUsICJpbnQiKSkKCXsKCSAgICB1Y3M0ID0gKEZjQ2hhcjMyKSBzdHJ0b2wgKEZjQ29uZmlnQ29udGVudCAoZG9jLCBub2RlKSwgMCwgMCk7CgkgICAgaWYgKCFjb25maWctPmJsYW5rcykKCSAgICB7CgkJY29uZmlnLT5ibGFua3MgPSBGY0JsYW5rc0NyZWF0ZSAoKTsKCQlpZiAoIWNvbmZpZy0+YmxhbmtzKQoJCSAgICBicmVhazsKCSAgICB9CgkgICAgaWYgKCFGY0JsYW5rc0FkZCAoY29uZmlnLT5ibGFua3MsIHVjczQpKQoJCWJyZWFrOwoJfQogICAgfQogICAgaWYgKG5vZGUpCglyZXR1cm4gRmNGYWxzZTsKICAgIHJldHVybiBGY1RydWU7Cn0KCnN0YXRpYyBGY0Jvb2wKRmNDb25maWdQYXJzZUNvbmZpZyAoRmNDb25maWcJICAgICpjb25maWcsCgkJICAgICB4bWxEb2NQdHIJICAgIGRvYywKCQkgICAgIHhtbE5vZGVQdHIJICAgIGNmZykKewogICAgeG1sTm9kZQkqbm9kZTsKCiAgICBmb3IgKG5vZGUgPSBjZmctPmNoaWxkcmVuOyBub2RlOyBub2RlID0gbm9kZS0+bmV4dCkKICAgIHsKCWlmIChub2RlLT50eXBlICE9IFhNTF9FTEVNRU5UX05PREUpCgkgICAgY29udGludWU7CglpZiAoIXN0cmNtcCAobm9kZS0+bmFtZSwgImJsYW5rIikpCgl7CgkgICAgaWYgKCFGY0NvbmZpZ1BhcnNlQmxhbmsgKGNvbmZpZywgZG9jLCBub2RlKSkKCQlicmVhazsKCX0KICAgIH0KICAgIGlmIChub2RlKQoJcmV0dXJuIEZjRmFsc2U7CiAgICByZXR1cm4gRmNUcnVlOwp9CgpzdGF0aWMgRmNNYXRyaXggKgpGY0NvbmZpZ1BhcnNlTWF0cml4ICh4bWxEb2NQdHIJZG9jLAoJCSAgICAgeG1sTm9kZVB0cglub2RlKQp7CiAgICBzdGF0aWMgRmNNYXRyaXggbTsKICAgIGVudW0geyBtX3h4LCBtX3h5LCBtX3l4LCBtX3l5LCBtX2RvbmUgfSBtYXRyaXhfc3RhdGUgPSBtX3h4OwogICAgZG91YmxlICB2OwogICAgY2hhciAgICAqdGV4dDsKICAgIAogICAgRmNNYXRyaXhJbml0ICgmbSk7CgogICAgZm9yICg7IG5vZGU7IG5vZGUgPSBub2RlLT5uZXh0KQogICAgewoJaWYgKG5vZGUtPnR5cGUgIT0gWE1MX0VMRU1FTlRfTk9ERSkKCSAgICBjb250aW51ZTsKCWlmIChzdHJjbXAgKG5vZGUtPm5hbWUsICJkb3VibGUiKSkKCSAgICBjb250aW51ZTsKCXRleHQgPSBGY0NvbmZpZ0NvbnRlbnQgKGRvYywgbm9kZSk7CglpZiAoIXRleHQpCgkgICAgY29udGludWU7Cgl2ID0gc3RydG9kICh0ZXh0LCAwKTsKCXN3aXRjaCAobWF0cml4X3N0YXRlKSB7CgljYXNlIG1feHg6IG0ueHggPSB2OyBicmVhazsKCWNhc2UgbV94eTogbS54eSA9IHY7IGJyZWFrOwoJY2FzZSBtX3l4OiBtLnl4ID0gdjsgYnJlYWs7CgljYXNlIG1feXk6IG0ueXkgPSB2OyBicmVhazsKCWRlZmF1bHQ6IGJyZWFrOwoJfQoJbWF0cml4X3N0YXRlKys7CiAgICB9CgkgCiAgICByZXR1cm4gJm07Cn0KCnN0YXRpYyBGY0V4cHIgKgpGY0NvbmZpZ1BhcnNlRXhwciAoeG1sRG9jUHRyCWRvYywKCQkgICB4bWxOb2RlUHRyCWV4cHIpCnsKICAgIEZjT3AJb3AgPSBGY0NvbmZpZ0xleE9wIChleHByLT5uYW1lKTsKICAgIHhtbE5vZGVQdHIJbm9kZTsKICAgIEZjRXhwcgkqbCA9IDAsICplID0gMCwgKnIgPSAwLCAqYyA9IDA7CgogICAgc3dpdGNoIChvcCkgewogICAgY2FzZSBGY09wSW50ZWdlcjoKCWwgPSBGY0V4cHJDcmVhdGVJbnRlZ2VyIChzdHJ0b2wgKEZjQ29uZmlnQ29udGVudCAoZG9jLCBleHByKSwgMCwgMCkpOwoJYnJlYWs7CiAgICBjYXNlIEZjT3BEb3VibGU6CglsID0gRmNFeHByQ3JlYXRlRG91YmxlIChzdHJ0b2QgKEZjQ29uZmlnQ29udGVudCAoZG9jLCBleHByKSwgMCkpOwoJYnJlYWs7CiAgICBjYXNlIEZjT3BTdHJpbmc6CglsID0gRmNFeHByQ3JlYXRlU3RyaW5nIChGY0NvbmZpZ0NvbnRlbnQgKGRvYywgZXhwcikpOwoJYnJlYWs7CiAgICBjYXNlIEZjT3BNYXRyaXg6CglsID0gRmNFeHByQ3JlYXRlTWF0cml4IChGY0NvbmZpZ1BhcnNlTWF0cml4IChkb2MsIGV4cHIpKTsKCWJyZWFrOwogICAgY2FzZSBGY09wQm9vbDoKCWwgPSBGY0V4cHJDcmVhdGVCb29sIChGY0NvbmZpZ0xleEJvb2woRmNDb25maWdDb250ZW50IChkb2MsIGV4cHIpKSk7CglicmVhazsKICAgIGNhc2UgRmNPcENoYXJTZXQ6CgkvKiBub3Qgc3VyZSB3aGF0IHRvIGRvIGhlcmUgeWV0ICovCglicmVhazsKICAgIGNhc2UgRmNPcEZpZWxkOgoJbCA9IEZjRXhwckNyZWF0ZUZpZWxkIChGY0NvbmZpZ0NvbnRlbnQgKGRvYywgZXhwcikpOwoJYnJlYWs7CiAgICBjYXNlIEZjT3BDb25zdDoKCWwgPSBGY0V4cHJDcmVhdGVDb25zdCAoRmNDb25maWdDb250ZW50IChkb2MsIGV4cHIpKTsKCWJyZWFrOwogICAgY2FzZSBGY09wUXVlc3Q6Cglmb3IgKG5vZGUgPSBleHByLT5jaGlsZHJlbjsgbm9kZTsgbm9kZSA9IG5vZGUtPm5leHQpCgl7CgkgICAgaWYgKG5vZGUtPnR5cGUgIT0gWE1MX0VMRU1FTlRfTk9ERSkKCQljb250aW51ZTsKCSAgICBlID0gRmNDb25maWdQYXJzZUV4cHIgKGRvYywgbm9kZSk7CgkgICAgaWYgKCFlKQoJCWJyZWFrOwoJICAgIGlmICghbCkKCQlsID0gZTsKCSAgICBlbHNlIGlmICghYykKCQljID0gZTsKCSAgICBlbHNlIGlmICghcikKCQlyID0gZTsKCSAgICBlbHNlCgkJRmNFeHByRGVzdHJveSAoZSk7Cgl9CgllID0gMDsKCWlmICghbm9kZSAmJiBsICYmIGMgJiYgcikKCXsKCSAgICBlID0gRmNFeHByQ3JlYXRlT3AgKGMsIEZjT3BRdWVzdCwgcik7CgkgICAgaWYgKGUpCgkgICAgewoJCXIgPSBlOwoJCWMgPSAwOwoJCWUgPSBGY0V4cHJDcmVhdGVPcCAobCwgRmNPcFF1ZXN0LCByKTsKCSAgICB9CgkgICAgaWYgKCFlKQoJCW5vZGUgPSBleHByLT5jaGlsZHJlbjsKCX0KCWlmIChub2RlIHx8ICFsIHx8ICFjIHx8ICFyIHx8ICFlKQoJewoJICAgIGlmIChsKQoJCUZjRXhwckRlc3Ryb3kgKGwpOwoJICAgIGlmIChjKQoJCUZjRXhwckRlc3Ryb3kgKGMpOwoJICAgIGlmIChyKQoJCUZjRXhwckRlc3Ryb3kgKHIpOwoJICAgIHJldHVybiAwOwoJfQoJYnJlYWs7CiAgICBkZWZhdWx0OgoJZm9yIChub2RlID0gZXhwci0+Y2hpbGRyZW47IG5vZGU7IG5vZGUgPSBub2RlLT5uZXh0KQoJewoJICAgIGlmIChub2RlLT50eXBlICE9IFhNTF9FTEVNRU5UX05PREUpCgkJY29udGludWU7CgkgICAgZSA9IEZjQ29uZmlnUGFyc2VFeHByIChkb2MsIG5vZGUpOwoJICAgIGlmICghZSkKCQlicmVhazsKCSAgICBpZiAoIWwpCgkJbCA9IGU7CgkgICAgZWxzZQoJICAgIHsKCQlyID0gZTsKCQllID0gRmNFeHByQ3JlYXRlT3AgKGwsIG9wLCByKTsKCQlpZiAoIWUpCgkJewoJCSAgICBGY0V4cHJEZXN0cm95IChyKTsKCQkgICAgYnJlYWs7CgkJfQoJCWwgPSBlOwoJICAgIH0KCX0KCWlmIChub2RlIHx8ICFsKQoJewoJICAgIGlmIChsKQoJCUZjRXhwckRlc3Ryb3kgKGwpOwoJICAgIHJldHVybiAwOwoJfQoJLyoKCSAqIFNwZWNpYWwgY2FzZSBmb3IgdW5hcnkgb3BzIAoJICovCglpZiAoIXIpCgl7CgkgICAgZSA9IEZjRXhwckNyZWF0ZU9wIChsLCBvcCwgMCk7CgkgICAgaWYgKCFlKQoJICAgIHsKCQlGY0V4cHJEZXN0cm95IChsKTsKCQlyZXR1cm4gMDsKCSAgICB9Cgl9CglicmVhazsKICAgIAogICAgY2FzZSBGY09wSW52YWxpZDoKCXJldHVybiAwOwogICAgfQogICAgcmV0dXJuIGw7Cn0KCnN0YXRpYyBGY1Rlc3QgKgpGY0NvbmZpZ1BhcnNlVGVzdCAoeG1sRG9jUHRyCWRvYywKCQkgICB4bWxOb2RlUHRyCXRlc3QpCnsKICAgIHhtbE5vZGVQdHIJbm9kZTsKICAgIHhtbEF0dHJQdHIJYXR0cjsKICAgIEZjUXVhbAlxdWFsID0gRmNRdWFsQW55OwogICAgRmNPcAlvcCA9IEZjT3BFcXVhbDsKICAgIGNoYXIJKmZpZWxkID0gMDsKICAgIEZjRXhwcgkqZXhwciA9IDA7CgogICAgZm9yIChhdHRyID0gdGVzdC0+cHJvcGVydGllczsgYXR0cjsgYXR0ciA9IGF0dHItPm5leHQpCiAgICB7CglpZiAoYXR0ci0+dHlwZSAhPSBYTUxfQVRUUklCVVRFX05PREUpCgkgICAgY29udGludWU7CglpZiAoIXN0cmNtcCAoYXR0ci0+bmFtZSwgInF1YWwiKSkKCXsKCSAgICBjaGFyICAgICpxdWFsX25hbWUgPSBGY0NvbmZpZ0F0dHIgKGRvYywgYXR0cik7CgkgICAgaWYgKCFxdWFsX25hbWUpCgkJOwoJICAgIGVsc2UgaWYgKCFzdHJjbXAgKHF1YWxfbmFtZSwgImFueSIpKQoJCXF1YWwgPSBGY1F1YWxBbnk7CgkgICAgZWxzZSBpZiAoIXN0cmNtcCAocXVhbF9uYW1lLCAiYWxsIikpCgkJcXVhbCA9IEZjUXVhbEFsbDsKCX0KCWVsc2UgaWYgKCFzdHJjbXAgKGF0dHItPm5hbWUsICJuYW1lIikpCgl7CgkgICAgZmllbGQgPSBGY0NvbmZpZ0F0dHIgKGRvYywgYXR0cik7Cgl9CgllbHNlIGlmICghc3RyY21wIChhdHRyLT5uYW1lLCAiY29tcGFyZSIpKQoJewoJICAgIGNoYXIgICAgKmNvbXBhcmUgPSBGY0NvbmZpZ0F0dHIgKGRvYywgYXR0cik7CgkgICAgCgkgICAgaWYgKCFjb21wYXJlIHx8IChvcCA9IEZjQ29uZmlnTGV4T3AgKGNvbXBhcmUpKSA9PSBGY09wSW52YWxpZCkKCSAgICB7CgkJRmNDb25maWdQYXJzZUVycm9yICgiSW52YWxpZCBjb21wYXJpc29uICVzIiwgCgkJCQkgICAgY29tcGFyZSA/IGNvbXBhcmUgOiAiPG1pc3Npbmc+Iik7CgkJcmV0dXJuIDA7CgkgICAgfQoJfQogICAgfQogICAgaWYgKGF0dHIpCglyZXR1cm4gMDsKCiAgICBmb3IgKG5vZGUgPSB0ZXN0LT5jaGlsZHJlbjsgbm9kZTsgbm9kZSA9IG5vZGUtPm5leHQpCiAgICB7CglpZiAobm9kZS0+dHlwZSAhPSBYTUxfRUxFTUVOVF9OT0RFKQoJICAgIGNvbnRpbnVlOwoJZXhwciA9IEZjQ29uZmlnUGFyc2VFeHByIChkb2MsIG5vZGUpOwoJaWYgKCFleHByKQoJICAgIHJldHVybiAwOwoJYnJlYWs7CiAgICB9CgogICAgaWYgKCFleHByKQogICAgewoJRmNDb25maWdQYXJzZUVycm9yICgiTWlzc2luZyB0ZXN0IGV4cHJlc3Npb24iKTsKCXJldHVybiAwOwogICAgfQogICAgCiAgICByZXR1cm4gRmNUZXN0Q3JlYXRlIChxdWFsLCBmaWVsZCwgb3AsIGV4cHIpOwp9CgpzdGF0aWMgRmNFeHByICoKRmNDb25maWdQYXJzZUV4cHJMaXN0ICh4bWxEb2NQdHIgICAgZG9jLAoJCSAgICAgICB4bWxOb2RlUHRyICAgZXhwcikKewogICAgRmNFeHByICAqbCwgKmUsICpyOwogICAgCiAgICBpZiAoIWV4cHIpCglyZXR1cm4gMDsKICAgIAogICAgZSA9IEZjQ29uZmlnUGFyc2VFeHByTGlzdCAoZG9jLCBleHByLT5uZXh0KTsKCiAgICBpZiAoZXhwci0+dHlwZSA9PSBYTUxfRUxFTUVOVF9OT0RFKQogICAgewoJciA9IGU7CglsID0gRmNDb25maWdQYXJzZUV4cHIgKGRvYywgZXhwcik7CglpZiAoIWwpCgkgICAgZ290byBiYWlsOwoJaWYgKHIpCgl7CgkgICAgZSA9IEZjRXhwckNyZWF0ZU9wIChsLCBGY09wQ29tbWEsIHIpOwoJICAgIGlmICghZSkKCQlnb3RvIGJhaWw7Cgl9CgllbHNlCgkgICAgZSA9IGw7CiAgICB9CiAgICAKICAgIHJldHVybiBlOwpiYWlsOgogICAgaWYgKGwpCglGY0V4cHJEZXN0cm95IChsKTsKICAgIGlmIChyKQoJRmNFeHByRGVzdHJveSAocik7CiAgICByZXR1cm4gMDsKfQoKc3RhdGljIEZjRWRpdCAqCkZjQ29uZmlnUGFyc2VFZGl0ICh4bWxEb2NQdHIJZG9jLAoJCSAgIHhtbE5vZGVQdHIJZWRpdCkKewogICAgeG1sQXR0clB0cglhdHRyOwogICAgY2hhcgkqbmFtZSA9IDA7CiAgICBGY09wCW1vZGUgPSBGY09wQXNzaWduOwogICAgRmNFeHByCSplOwogICAgRmNFZGl0CSplZDsKCiAgICBmb3IgKGF0dHIgPSBlZGl0LT5wcm9wZXJ0aWVzOyBhdHRyOyBhdHRyID0gYXR0ci0+bmV4dCkKICAgIHsKCWlmIChhdHRyLT50eXBlICE9IFhNTF9BVFRSSUJVVEVfTk9ERSkKCSAgICBjb250aW51ZTsKCWlmICghc3RyY21wIChhdHRyLT5uYW1lLCAibmFtZSIpKQoJICAgIG5hbWUgPSBGY0NvbmZpZ0F0dHIgKGRvYywgYXR0cik7CgllbHNlIGlmICghc3RyY21wIChhdHRyLT5uYW1lLCAibW9kZSIpKQoJICAgIG1vZGUgPSBGY0NvbmZpZ0xleE9wIChGY0NvbmZpZ0F0dHIgKGRvYywgYXR0cikpOwogICAgfQoKICAgIGUgPSBGY0NvbmZpZ1BhcnNlRXhwckxpc3QgKGRvYywgZWRpdC0+Y2hpbGRyZW4pOwoKICAgIGVkID0gRmNFZGl0Q3JlYXRlIChuYW1lLCBtb2RlLCBlKTsKICAgIGlmICghZWQpCglGY0V4cHJEZXN0cm95IChlKTsKICAgIHJldHVybiBlZDsKfQoKc3RhdGljIEZjQm9vbApGY0NvbmZpZ1BhcnNlTWF0Y2ggKEZjQ29uZmlnCSpjb25maWcsCgkJICAgIHhtbERvY1B0cglkb2MsCgkJICAgIHhtbE5vZGVQdHIJbWF0Y2gpCnsKICAgIHhtbE5vZGVQdHIJbm9kZTsKICAgIHhtbEF0dHJQdHIJYXR0cjsKICAgIEZjVGVzdAkqdGVzdHMgPSAwLCAqKnByZXZUZXN0ID0gJnRlc3RzLCAqdGVzdDsKICAgIEZjRWRpdAkqZWRpdHMgPSAwLCAqKnByZXZFZGl0ID0gJmVkaXRzLCAqZWRpdDsKICAgIEZjTWF0Y2hLaW5kCWtpbmQ7CiAgICBGY0Jvb2wJZm91bmRfa2luZCA9IEZjRmFsc2U7CgogICAgZm9yIChub2RlID0gbWF0Y2gtPmNoaWxkcmVuOyBub2RlOyBub2RlID0gbm9kZS0+bmV4dCkKICAgIHsKCWlmIChub2RlLT50eXBlICE9IFhNTF9FTEVNRU5UX05PREUpCgkgICAgY29udGludWU7CglpZiAoIXN0cmNtcCAobm9kZS0+bmFtZSwgInRlc3QiKSkKCXsKCSAgICB0ZXN0ID0gRmNDb25maWdQYXJzZVRlc3QgKGRvYywgbm9kZSk7CgkgICAgaWYgKCF0ZXN0KQoJCWJyZWFrOwoJICAgICpwcmV2VGVzdCA9IHRlc3Q7CgkgICAgcHJldlRlc3QgPSAmdGVzdC0+bmV4dDsKCX0KCWVsc2UgaWYgKCFzdHJjbXAgKG5vZGUtPm5hbWUsICJlZGl0IikpCgl7CgkgICAgZWRpdCA9IEZjQ29uZmlnUGFyc2VFZGl0IChkb2MsIG5vZGUpOwoJICAgIGlmICghZWRpdCkKCQlicmVhazsKCSAgICAqcHJldkVkaXQgPSBlZGl0OwoJICAgIHByZXZFZGl0ID0gJmVkaXQtPm5leHQ7Cgl9CiAgICB9CgogICAgZm9yIChhdHRyID0gbWF0Y2gtPnByb3BlcnRpZXM7IGF0dHI7IGF0dHIgPSBhdHRyLT5uZXh0KQogICAgewoJaWYgKGF0dHItPnR5cGUgIT0gWE1MX0FUVFJJQlVURV9OT0RFKQoJICAgIGNvbnRpbnVlOwoJaWYgKCFzdHJjbXAgKGF0dHItPm5hbWUsICJ0YXJnZXQiKSkKCXsKCSAgICBjaGFyICAgICp0YXJnZXQgPSBGY0NvbmZpZ0F0dHIgKGRvYywgYXR0cik7CgkgICAgaWYgKCF0YXJnZXQpCgkgICAgewoJCUZjQ29uZmlnUGFyc2VFcnJvciAoIk1pc3NpbmcgbWF0Y2ggdGFyZ2V0Iik7CgkJYnJlYWs7CgkgICAgfQoJICAgIGVsc2UgaWYgKCFzdHJjbXAgKHRhcmdldCwgInBhdHRlcm4iKSkKCSAgICB7CgkJa2luZCA9IEZjTWF0Y2hQYXR0ZXJuOwoJCWZvdW5kX2tpbmQgPSBGY1RydWU7CgkgICAgfQoJICAgIGVsc2UgaWYgKCFzdHJjbXAgKHRhcmdldCwgImZvbnQiKSkKCSAgICB7CgkJa2luZCA9IEZjTWF0Y2hGb250OwoJCWZvdW5kX2tpbmQgPSBGY1RydWU7CgkgICAgfQoJfQogICAgfQoKICAgIGlmIChub2RlIHx8IGF0dHIgfHwgIWZvdW5kX2tpbmQgfHwgCgkhRmNDb25maWdBZGRFZGl0IChjb25maWcsIHRlc3RzLCBlZGl0cywga2luZCkpCiAgICB7CglpZiAodGVzdHMpCgkgICAgRmNUZXN0RGVzdHJveSAodGVzdHMpOwoJaWYgKGVkaXRzKQoJICAgIEZjRWRpdERlc3Ryb3kgKGVkaXRzKTsKCXJldHVybiBGY0ZhbHNlOwogICAgfQoKICAgIHJldHVybiBGY1RydWU7Cn0KCnN0YXRpYyBGY0V4cHIgKgpGY0NvbmZpZ1BhcnNlRmFtaWxpZXMgKHhtbERvY1B0ciAgICBkb2MsCgkJICAgICAgIHhtbE5vZGVQdHIgICBmYW1pbHkpCnsKICAgIEZjRXhwciAgKm5leHQgPSAwLCAqdGhpcyA9IDAsICpleHByID0gMDsKICAgIAogICAgaWYgKCFmYW1pbHkpCglyZXR1cm4gMDsKICAgIG5leHQgPSBGY0NvbmZpZ1BhcnNlRmFtaWxpZXMgKGRvYywgZmFtaWx5LT5uZXh0KTsKICAgIAogICAgaWYgKGZhbWlseS0+dHlwZSA9PSBYTUxfRUxFTUVOVF9OT0RFICYmICFzdHJjbXAgKGZhbWlseS0+bmFtZSwgImZhbWlseSIpKQogICAgewoJdGhpcyA9IEZjRXhwckNyZWF0ZVN0cmluZyAoRmNDb25maWdDb250ZW50IChkb2MsIGZhbWlseSkpOwoJaWYgKCF0aGlzKQoJICAgIGdvdG8gYmFpbDsKCWlmIChuZXh0KQoJewoJICAgIGV4cHIgPSBGY0V4cHJDcmVhdGVPcCAodGhpcywgRmNPcENvbW1hLCBuZXh0KTsKCSAgICBpZiAoIWV4cHIpCgkJZ290byBiYWlsOwoJfQoJZWxzZQoJICAgIGV4cHIgPSB0aGlzOwogICAgfQogICAgZWxzZQoJZXhwciA9IG5leHQ7CiAgICByZXR1cm4gZXhwcjsKCmJhaWw6CiAgICBpZiAoZXhwcikKCUZjRXhwckRlc3Ryb3kgKGV4cHIpOwogICAgaWYgKHRoaXMpCglGY0V4cHJEZXN0cm95ICh0aGlzKTsKICAgIGlmIChuZXh0KQoJRmNFeHByRGVzdHJveSAobmV4dCk7CiAgICByZXR1cm4gMDsKfQoKc3RhdGljIEZjQm9vbApGY0NvbmZpZ1BhcnNlQWxpYXMgKEZjQ29uZmlnCSpjb25maWcsCgkJICAgIHhtbERvY1B0cglkb2MsCgkJICAgIHhtbE5vZGVQdHIJYWxpYXMpCnsKICAgIHhtbE5vZGVQdHIJbm9kZTsKICAgIEZjRXhwcgkqcHJlZmVyID0gMCwgKmFjY2VwdCA9IDAsICpkZWYgPSAwOwogICAgRmNFeHByCSpmYW1pbHk7CiAgICBGY0VkaXQJKmVkaXQgPSAwLCAqbmV4dDsKICAgIEZjVGVzdAkqdGVzdDsKCiAgICBmb3IgKG5vZGUgPSBhbGlhcy0+Y2hpbGRyZW47IG5vZGU7IG5vZGUgPSBub2RlLT5uZXh0KQogICAgewoJaWYgKG5vZGUtPnR5cGUgIT0gWE1MX0VMRU1FTlRfTk9ERSkKCSAgICBjb250aW51ZTsKCWlmICghc3RyY21wIChub2RlLT5uYW1lLCAiZmFtaWx5IikpCgkgICAgZmFtaWx5ID0gRmNFeHByQ3JlYXRlU3RyaW5nIChGY0NvbmZpZ0NvbnRlbnQgKGRvYywgbm9kZSkpOwoJZWxzZSBpZiAoIXN0cmNtcCAobm9kZS0+bmFtZSwgInByZWZlciIpKQoJICAgIHByZWZlciA9IEZjQ29uZmlnUGFyc2VGYW1pbGllcyAoZG9jLCBub2RlLT5jaGlsZHJlbik7CgllbHNlIGlmICghc3RyY21wIChub2RlLT5uYW1lLCAiYWNjZXB0IikpCgkgICAgYWNjZXB0ID0gRmNDb25maWdQYXJzZUZhbWlsaWVzIChkb2MsIG5vZGUtPmNoaWxkcmVuKTsKCWVsc2UgaWYgKCFzdHJjbXAgKG5vZGUtPm5hbWUsICJkZWZhdWx0IikpCgkgICAgZGVmID0gRmNDb25maWdQYXJzZUZhbWlsaWVzIChkb2MsIG5vZGUtPmNoaWxkcmVuKTsKICAgIH0KICAgIAogICAgaWYgKHByZWZlcikKICAgIHsKCWVkaXQgPSBGY0VkaXRDcmVhdGUgKEZjQ29uZmlnU2F2ZUZpZWxkICgiZmFtaWx5IiksCgkJCSAgICAgRmNPcFByZXBlbmQsCgkJCSAgICAgcHJlZmVyKTsKCWlmIChlZGl0KQoJICAgIGVkaXQtPm5leHQgPSAwOwogICAgfQogICAgaWYgKGFjY2VwdCkKICAgIHsKCW5leHQgPSBlZGl0OwoJZWRpdCA9IEZjRWRpdENyZWF0ZSAoRmNDb25maWdTYXZlRmllbGQgKCJmYW1pbHkiKSwKCQkJICAgICBGY09wQXBwZW5kLAoJCQkgICAgIGFjY2VwdCk7CglpZiAoZWRpdCkKCSAgICBlZGl0LT5uZXh0ID0gbmV4dDsKICAgIH0KICAgIGlmIChkZWYpCiAgICB7CgluZXh0ID0gZWRpdDsKCWVkaXQgPSBGY0VkaXRDcmVhdGUgKEZjQ29uZmlnU2F2ZUZpZWxkICgiZmFtaWx5IiksCgkJCSAgICAgIEZjT3BBcHBlbmRMYXN0LAoJCQkgICAgICBkZWYpOwoJaWYgKGVkaXQpCgkgICAgZWRpdC0+bmV4dCA9IG5leHQ7CiAgICB9CiAgICBpZiAoZWRpdCkKICAgIHsKCXRlc3QgPSBGY1Rlc3RDcmVhdGUgKEZjUXVhbEFueSwKCQkJICAgICBGY0NvbmZpZ1NhdmVGaWVsZCAoImZhbWlseSIpLAoJCQkgICAgIEZjT3BFcXVhbCwKCQkJICAgICBmYW1pbHkpOwoJaWYgKHRlc3QpCgkgICAgRmNDb25maWdBZGRFZGl0IChjb25maWcsIHRlc3QsIGVkaXQsIEZjTWF0Y2hQYXR0ZXJuKTsKICAgIH0KICAgIHJldHVybiBGY1RydWU7Cn0KCkZjQm9vbApGY0NvbmZpZ1BhcnNlIChGY0NvbmZpZwkgICAgKmNvbmZpZywKCSAgICAgICB4bWxEb2NQdHIgICAgZG9jKQp7CiAgICB4bWxOb2RlUHRyCWN1cjsKICAgIHhtbE5vZGVQdHIJbm9kZTsKICAgIAogICAgY3VyID0geG1sRG9jR2V0Um9vdEVsZW1lbnQgKGRvYyk7CgogICAgZm9yIChub2RlID0gY3VyLT5jaGlsZHJlbjsgbm9kZTsgbm9kZSA9IG5vZGUtPm5leHQpCiAgICB7CglpZiAobm9kZS0+dHlwZSAhPSBYTUxfRUxFTUVOVF9OT0RFKQoJICAgIGNvbnRpbnVlOwoJaWYgKCFzdHJjbXAgKG5vZGUtPm5hbWUsICJkaXIiKSkKCXsKCSAgICBpZiAoIUZjQ29uZmlnUGFyc2VEaXIgKGNvbmZpZywgZG9jLCBub2RlKSkKCQlicmVhazsKCX0KCWVsc2UgaWYgKCFzdHJjbXAgKG5vZGUtPm5hbWUsICJjYWNoZSIpKQoJewoJICAgIGlmICghRmNDb25maWdQYXJzZUNhY2hlIChjb25maWcsIGRvYywgbm9kZSkpCgkJYnJlYWs7Cgl9CgllbHNlIGlmICghc3RyY21wIChub2RlLT5uYW1lLCAiaW5jbHVkZSIpKQoJewoJICAgIGlmICghRmNDb25maWdQYXJzZUluY2x1ZGUgKGNvbmZpZywgZG9jLCBub2RlKSkKCQlicmVhazsKCX0KCWVsc2UgaWYgKCFzdHJjbXAgKG5vZGUtPm5hbWUsICJjb25maWciKSkKCXsKCSAgICBpZiAoIUZjQ29uZmlnUGFyc2VDb25maWcgKGNvbmZpZywgZG9jLCBub2RlKSkKCQlicmVhazsKCX0KCWVsc2UgaWYgKCFzdHJjbXAgKG5vZGUtPm5hbWUsICJtYXRjaCIpKQoJewoJICAgIGlmICghRmNDb25maWdQYXJzZU1hdGNoIChjb25maWcsIGRvYywgbm9kZSkpCgkJYnJlYWs7Cgl9CgllbHNlIGlmICghc3RyY21wIChub2RlLT5uYW1lLCAiYWxpYXMiKSkKCXsKCSAgICBpZiAoIUZjQ29uZmlnUGFyc2VBbGlhcyAoY29uZmlnLCBkb2MsIG5vZGUpKQoJCWJyZWFrOwoJfQoJZWxzZQoJewoJICAgIEZjQ29uZmlnUGFyc2VFcnJvciAoImludmFsaWQgZWxlbWVudCAlcyIsIG5vZGUtPm5hbWUpOwoJICAgIGJyZWFrOwoJfSAgIAogICAgfQogICAgaWYgKG5vZGUpCglyZXR1cm4gRmNGYWxzZTsKICAgIHJldHVybiBGY1RydWU7Cn0KCkZjQm9vbApGY0NvbmZpZ1BhcnNlQW5kTG9hZCAoRmNDb25maWcJICAgICpjb25maWcsCgkJICAgICAgY29uc3QgY2hhciAgICAqZmlsZSwKCQkgICAgICBGY0Jvb2wJICAgIGNvbXBsYWluKQp7CiAgICB4bWxEb2NQdHIJZG9jOwogICAgRmNCb29sCXJldDsKCiAgICBkb2MgPSBGY0NvbmZpZ0xvYWQgKGZpbGUpOwogICAgaWYgKGRvYykKICAgIHsKCXJldCA9IEZjQ29uZmlnQWRkQ29uZmlnRmlsZSAoY29uZmlnLCBmaWxlKTsKCWlmIChyZXQpCgkgICAgcmV0ID0gRmNDb25maWdQYXJzZSAoY29uZmlnLCBkb2MpOwoJeG1sRnJlZURvYyAoZG9jKTsKCXJldHVybiByZXQ7CiAgICB9CiAgICBpZiAoY29tcGxhaW4pCiAgICB7CglpZiAoZmlsZSkKCSAgICBGY0NvbmZpZ1BhcnNlRXJyb3IgKCJDYW5ub3QgbG9hZCBjb25maWcgZmlsZSBcIiVzXCIiLCBmaWxlKTsKCWVsc2UKCSAgICBGY0NvbmZpZ1BhcnNlRXJyb3IgKCJDYW5ub3QgbG9hZCBkZWZhdWx0IGNvbmZpZyBmaWxlIik7CglyZXR1cm4gRmNGYWxzZTsKICAgIH0KICAgIHJldHVybiBGY1RydWU7Cn0K