ZGlmZiAtLWdpdCBhL2FwL2xpYi9saWJ3bGFuX2ludGVyZmFjZS9icm9hZGNvbV9pbnRlcmZhY2UuYyBiL2FwL2xpYi9saWJ3bGFuX2ludGVyZmFjZS9icm9hZGNvbV9pbnRlcmZhY2UuYwpuZXcgZmlsZSBtb2RlIDEwMDc1NQppbmRleCAwMDAwMDAwLi4yOTQ3YzE3Ci0tLSAvZGV2L251bGwKKysrIGIvYXAvbGliL2xpYndsYW5faW50ZXJmYWNlL2Jyb2FkY29tX2ludGVyZmFjZS5jCkBAIC0wLDAgKzEsNzY3IEBACisjaW5jbHVkZSA8c29mdGFwX2FwaS5oPg0KKyNpbmNsdWRlIDxlcnJuby5oPg0KKyNpbmNsdWRlICJ3bGFuX2ludGVyZmFjZS5oIg0KKw0KKyNkZWZpbmUgV0lGSV9TU0lEX0xFTiAzMw0KKw0KKyNkZWZpbmUgV0xBTl9TRUNVUklUWV9MRU4gMjANCisjZGVmaW5lIFdMQU5fRU5DUllUWVBFX0xFTiAxMA0KKyNkZWZpbmUgV0xBTl9ERUZBVUxUSURfTEVOIDINCisjZGVmaW5lIFdMQU5fV0VQS0VZX0xFTiAzMg0KKyNkZWZpbmUgV0xBTl9QU0tfTEVOIDY1DQorI2RlZmluZSBXTEFOX0VOQ09ERV9QU0tfTEVOIDEwMA0KKw0KKyNkZWZpbmUgV0ZfQVVfT1BFTiAgICAgICAgICAiT1BFTiIgICAgICAgICAgICAvL3dpZmkgYXV0aCBtb2RlPw0KKyNkZWZpbmUgV0ZfQVVfU0hBUkUgICAgICAgICAiU0hBUkVEIg0KKyNkZWZpbmUgV0ZfQVVfV0VQQVVUTyAgICAgICAiV0VQQVVUTyINCisjZGVmaW5lIFdGX0FVX1dQQSAgICAgICAgICAgIldQQVBTSyINCisjZGVmaW5lIFdGX0FVX1dQQTIgICAgICAgICAgIldQQTJQU0siDQorI2RlZmluZSBXRl9BVV9XUEFfV1BBMiAgCSJXUEFQU0tXUEEyUFNLIiANCisjZGVmaW5lIFdGX0FVX1dBUElQU0sJICAgICJXQVBJUFNLIg0KKyNkZWZpbmUgV0ZfRU5DUllfTk9ORSAgIk5PTkUiICAgLy9lbmNyeXB0DQorI2RlZmluZSBXRl9FTkNSWV9XRVAgICAgIldFUCINCisjZGVmaW5lIFdGX0VOQ1JZX1RLSVAgICAiVEtJUCINCisjZGVmaW5lIFdGX0VOQ1JZX0NDTVAgICJDQ01QIg0KKyNkZWZpbmUgV0ZfRU5DUllfQUVTICAgICJBRVMiDQorI2RlZmluZSBXRl9FTkNSWV9US0lQX0NDTVAgIlRLSVBDQ01QIg0KKyNkZWZpbmUgV0ZfRU5DUllfVEtJUF9BRVMgIlRLSVBBRVMiDQorDQorc3RhdGljIHZvaWQgenRlX3dsYW5fZ2V0X3dpZmlfc3RhdGlvbl9saXN0KFJUXzgwMl8xMV9NQUNfVEFCTEUgKnN0YWlvbmxpc3QpOw0KKw0KKw0KK3ZvaWQgenRlX3dsYW5fZ2V0X3dpZmlfbWFjX2xpc3QoUlRfODAyXzExX01BQ19UQUJMRSAqbWFjbGlzdCkNCit7DQorICAgIGludCBzID0gMDsNCisgICAgaW50IGsgPSAwOw0KKw0KKyAgICBGSUxFICpwcCA9IE5VTEw7DQorICAgIC8vRklMRSAqcHAyID0gTlVMTDsNCisgICAgY2hhciBidWZbMTI4XT17MH07DQorICAgIGNoYXIgbWFjX3RtcFsxOF0gPSB7MH07DQorICAgIGNoYXIgbnVtX3RtcFszXSA9IHswfTsNCisgICAgY2hhciAqcCA9IE5VTEw7DQorICAgIGNoYXIgKnBfdG1wID0gTlVMTDsNCisNCisgICAgY2hhciBhdXRobW9kZVsyMF09ezB9Ow0KKyAgICBjaGFyIGVuY3J5cHR5cGVbMjBdPXswfTsNCisgICAgDQorICAgIGNoYXIgd2lmaV9zdGFfY29ubmVjdGlvbls4XT17MH07DQorICAgIA0KKyAgICBjaGFyIGNtZFsxMjhdPXswfTsNCisgICAgY2hhciBpaWZuYW1lWzIwXT17MH07DQorICAgIFJUXzgwMl8xMV9NQUNfVEFCTEUgKm1hY19saXN0PU5VTEwgOw0KKyAgICBtZW1zZXQoYnVmLCAwLCBzaXplb2YoYnVmKSk7IA0KKyAgICBtYWNfbGlzdCA9KFJUXzgwMl8xMV9NQUNfVEFCTEUqKW1hbGxvYyhzaXplb2YoUlRfODAyXzExX01BQ19UQUJMRSkpOw0KKyAgICBpZihtYWNfbGlzdCA9PSBOVUxMKQ0KKyAgICB7DQorICAgICAgICAgICAgYXNzZXJ0KG1hY19saXN0KTsNCisgICAgfQ0KKyAgICBlbHNlDQorICAgIHsNCisgICAgICAgIG1lbXNldChtYWNfbGlzdCwgMCwgc2l6ZW9mKFJUXzgwMl8xMV9NQUNfVEFCTEUpKTsNCisgICAgfQ0KKyAgIA0KKyAgICANCisgICAgc2NfY2ZnX2dldCgid2lmaV9zdGFfY29ubmVjdGlvbiIsIHdpZmlfc3RhX2Nvbm5lY3Rpb24sIHNpemVvZih3aWZpX3N0YV9jb25uZWN0aW9uKSk7DQorICAgDQorICAgIGlmKHN0cm5jbXAod2lmaV9zdGFfY29ubmVjdGlvbiwgIjEiLDEpID09IDApew0KKyAgICAgICAgc3RyY3B5KGlpZm5hbWUsIi1pIHdsMC4xIik7DQorICAgIH0NCisNCisgICAgLy9tZW1zZXQoJnRhYmxlLDAsc2l6ZW9mKHRhYmxlKSk7DQorDQorICAgIHNjX2NmZ19nZXQoIkF1dGhNb2RlIixhdXRobW9kZSxzaXplb2YoYXV0aG1vZGUpKTsNCisgICAgc2NfY2ZnX2dldCgiRW5jcnlwVHlwZSIsZW5jcnlwdHlwZSxzaXplb2YoZW5jcnlwdHlwZSkpOw0KKyAgICBpZigoIXN0cmNtcChhdXRobW9kZSwiV1BBUFNLIikpfHwoIXN0cmNtcChhdXRobW9kZSwiV1BBMlBTSyIpKXx8KCFzdHJjbXAoYXV0aG1vZGUsIldQQVBTS1dQQTJQU0siKSkpDQorICAgIHsNCisgICAgICAgIHNwcmludGYoY21kLCJ3bCAlcyBhdXRob19zdGFfbGlzdCIsaWlmbmFtZSk7DQorICAgIH0NCisgICAgZWxzZQ0KKyAgICB7DQorICAgICAgICBzcHJpbnRmKGNtZCwid2wgJXMgYXNzb2NsaXN0IixpaWZuYW1lKTsNCisgICAgfQ0KKyAgICBwcmludGYoIlslczolc11paWZuYW1lOiVzXG4iLF9fRklMRV9fLCBfX0ZVTkNUSU9OX18sIGNtZCk7DQorICAgIHBwID0gcG9wZW4oY21kLCAiciIpOyAvL72owaK53LXADQorICAgIGlmICghcHApDQorICAgIHsNCisgICAgICAgIHJldHVybiA7DQorICAgICAgICANCisgICAgfSANCisgICAgDQorICAgIHN0cmNweShidWYsIkFCTk9STUFMIik7DQorYWdhaW46ICAgICAgIA0KKyAgICB3aGlsZShmZ2V0cyhidWYsIDEyOCwgcHApICE9IE5VTEwpICAgICAgICANCisgICAgeyAgICAgICAgICAgICANCisgICAgICAgIA0KKyAgICAgICAgaWYoc3RyY21wKGJ1ZiwiQUJOT1JNQUwiKT09MCkgIC8qcHMgY29tbWFuZCBlcnJvciovICANCisgICAgICAgIHsNCisgICAgICAgICAgICBwcmludGYoIlslc10gZGV0ZWN0X3Byb2Nlc3Mgc3RyZXJyb3I6ICVzXG4iLF9fRlVOQ1RJT05fXyxzdHJlcnJvcihlcnJubykpOw0KKyAgICAgICAgICAgIGlmKGVycm5vID09IEVJTlRSKSAvL0ludGVycnVwdGVkIHN5c3RlbSBjYWxsLLTLyrG/ydbYytQNCisgICAgICAgICAgICB7DQorICAgICAgICAgICAgICAgIGdvdG8gYWdhaW47DQorICAgICAgICAgICAgfQ0KKyAgICAgICAgICAgIA0KKyAgICAgICAgICAgIHBjbG9zZShwcCk7Ly+52LHVudy1wA0KKyAgICAgICAgICAgIHJldHVybiA7IA0KKyAgICAgICAgIH0NCisgICAgICAgICBtZW1zZXQobWFjX3RtcCwgMCwgMTgpOyAgICAgICAgICAgIA0KKyAgICAgICAgIGlmKChwID0gc3Ryc3RyKGJ1ZiwgIjoiKSkgIT0gTlVMTCkgICAgICAgICAgICANCisgICAgICAgICB7ICAgICAgICAgICAgICAgIA0KKyAgICAgICAgICAgICBwX3RtcCA9IHAtMjsgICAgICAgICAgICAgICANCisgICAgICAgICAgICAgc3RybmNweShtYWNfdG1wLCBwX3RtcCwgMTcpOyAgICAgICAgICAgICAgIA0KKyAgICAgICAgICAgICAgICAgICAgICAgICANCisgICAgICAgICAgICAgZm9yKHM9MCxrPTA7IHM8NjsgcysrLGsrPTMpICAgICAgICAgICAgICAgIA0KKyAgICAgICAgICAgICB7ICAgICAgICAgICAgICAgICAgICANCisgICAgICAgICAgICAgICAgIHN0cm5jcHkobnVtX3RtcCwgbWFjX3RtcCArIGssIDIpOyAgICAgICAgICAgICAgICAgICANCisgICAgICAgICAgICAgICAgLy9wcmludGYoInpob3V0aSBudW1fdG1wIGlzICVzXG4iLCBudW1fdG1wKTsgICAgICAgICAgICAgICAgICAgIA0KKyAgICAgICAgICAgICAgICAvL3RhYmxlLkVudHJ5W3N0YV9udW1dLkFkZHJbc109YXRvaShudW1fdG1wKTsgICAgICAgICAgICAgICAgICAgIA0KKyAgICAgICAgICAgICAgICBtYWNfbGlzdC0+RW50cnlbbWFjX2xpc3QtPk51bV0uQWRkcltzXSA9IHMyeChudW1fdG1wKTsgIA0KKyAgICAgICAgICAgICAgICAvL21hY19saXN0LT5FbnRyeVttYWNfbGlzdC0+TnVtXS5BZGRyW3NdID0gMDsgDQorICAgICAgICAgICAgIH0gICAgICAgICAgICAgICAgDQorICAgICAgICAgICAgIG1hY19saXN0LT5OdW0gKz0gMTsgIA0KKyAgICAgICAgICAgIA0KKyAgICAgICAgIH0gICAgICAgICAgICANCisgICAgICAgIG1lbXNldChidWYsIDAsIHNpemVvZihidWYpKTsgICAgICAgIA0KKyAgICB9ICAgIA0KKyAgICAoKm1hY2xpc3QpPSAoKm1hY19saXN0KTsNCisgICAgaWYobWFjX2xpc3QpIA0KKyAgICB7DQorICAgICAgICBmcmVlKG1hY19saXN0KTsNCisgICAgICAgIG1hY19saXN0PU5VTEw7DQorICAgIH0NCisgICAgcGNsb3NlKHBwKTsgLy+52LHVudy1wDsNCisgICAgICAgICAgICANCit9DQorDQorc3RhdGljIHZvaWQgenRlX3dsYW5fZ2V0X3dpZmlfc3RhdGlvbl9saXN0KFJUXzgwMl8xMV9NQUNfVEFCTEUgKnN0YWlvbmxpc3QpDQoreyAgICANCisgICAgICAgIA0KKyAgICBpbnQgaSA9IDA7DQorICAgIGNoYXIgYnVmWzEyOF09ezB9Ow0KKyAgICBGSUxFICpwcDIgPSBOVUxMOw0KKyAgICBjaGFyIG1hY190bXBbMThdID0gezB9Ow0KKyAgICBjaGFyICpwX3RtcCA9IE5VTEw7DQorICAgIGNoYXIgc3RhdGlvbl9tYWNbMTgqMzJdPXswfTsgLy8gMDA6MDA6MDA6MDA6MDA6MDA7DQorICAgIGNoYXIgc3RhdGlvbmluZm9bMTAwXSA9IHswfTsNCisgICAgY2hhciBtYWNfdGltZVszM10gPSB7MH07DQorICAgIA0KKyAgICBSVF84MDJfMTFfTUFDX1RBQkxFICpzdGFfbGlzdCA9IE5VTEw7DQorICAgIHN0YV9saXN0ID0gKFJUXzgwMl8xMV9NQUNfVEFCTEUqKW1hbGxvYyhzaXplb2YoUlRfODAyXzExX01BQ19UQUJMRSkpOw0KKyAgICBpZihzdGFfbGlzdCA9PSBOVUxMKQ0KKyAgICB7DQorICAgICAgICAgICAgYXNzZXJ0KHN0YV9saXN0KTsNCisgICAgfQ0KKyAgICBlbHNlDQorICAgIHsNCisgICAgICAgIG1lbXNldChzdGFfbGlzdCwgMCwgc2l6ZW9mKFJUXzgwMl8xMV9NQUNfVEFCTEUpKzEpOw0KKyAgICB9DQorICAgIHp0ZV93bGFuX2dldF93aWZpX21hY19saXN0KHN0YV9saXN0KTsNCisNCisgICAgZm9yIChpID0gMDsgaSA8c3RhX2xpc3QtPk51bTsgaSsrKQ0KKyAgICB7DQorICAgICAgICBzcHJpbnRmKHN0YXRpb25fbWFjICsgaSAqIDE4LCAiJTIuMlg6JTIuMlg6JTIuMlg6JTIuMlg6JTIuMlg6JTIuMlg7IixcDQorICAgICAgICAgICAgICAgICAgIHN0YV9saXN0LT5FbnRyeVtpXS5BZGRyWzBdLCBzdGFfbGlzdC0+RW50cnlbaV0uQWRkclsxXSwNCisgICAgICAgICAgICAgICAgICAgIHN0YV9saXN0LT5FbnRyeVtpXS5BZGRyWzJdLCBzdGFfbGlzdC0+RW50cnlbaV0uQWRkclszXSwNCisgICAgICAgICAgICAgICAgICAgIHN0YV9saXN0LT5FbnRyeVtpXS5BZGRyWzRdLCBzdGFfbGlzdC0+RW50cnlbaV0uQWRkcls1XSk7DQorICAgICAgICBzcHJpbnRmKHN0YXRpb25pbmZvLCJ3bCBzdGFfaW5mbyAlMi4yWDolMi4yWDolMi4yWDolMi4yWDolMi4yWDolMi4yWCBcDQorICAgICAgICAgICAgfCBncmVwIFwiaW4gbmV0d29ya1wiIHwgY3V0IC1kXCIgXCIgLWY0IiwNCisgICAgICAgICAgICAgICAgICAgIHN0YV9saXN0LT5FbnRyeVtpXS5BZGRyWzBdLCBzdGFfbGlzdC0+RW50cnlbaV0uQWRkclsxXSwNCisgICAgICAgICAgICAgICAgICAgIHN0YV9saXN0LT5FbnRyeVtpXS5BZGRyWzJdLCBzdGFfbGlzdC0+RW50cnlbaV0uQWRkclszXSwNCisgICAgICAgICAgICAgICAgICAgIHN0YV9saXN0LT5FbnRyeVtpXS5BZGRyWzRdLCBzdGFfbGlzdC0+RW50cnlbaV0uQWRkcls1XSk7DQorICAgICAgICANCisgICAgICAgIHByaW50ZigiWyVzOiVzXXN0YXRpb25pbmZvOiVzXG4iLF9fRklMRV9fLCBfX0ZVTkNUSU9OX18sIHN0YXRpb25pbmZvKTsNCisgICAgICAgIHBwMiA9IHBvcGVuKHN0YXRpb25pbmZvLCAiciIpOyAvL72owaK53LXADQorICAgICAgICANCisgICAgICAgIGlmKE5VTEwgPT0gcHAyKSAgICANCisgICAgICAgIHsgICAgICAgIA0KKyAgICAgICAgICAgIGNvbnRpbnVlOw0KKyAgICAgICAgfSANCisgICAgICAgIG1lbXNldChidWYsIDAsIHNpemVvZihidWYpKTsgDQorICAgICAgICBzdHJjcHkoYnVmLCJBQk5PUk1BTCIpOw0KKyAgICAgICAgd2hpbGUoZmdldHMoYnVmLCBzaXplb2YoYnVmKSwgcHAyKSkNCisgICAgICAgIHsNCisNCisgICAgICAgICAgICBpZihzdHJjbXAoYnVmLCJBQk5PUk1BTCIpPT0wKSAgLypwcyBjb21tYW5kIGVycm9yKi8gIA0KKyAgICAgICAgICAgIHsNCisgICAgICAgICAgICAgICAgcHJpbnRmKCJbJXNdIGRldGVjdF9wcm9jZXNzIHN0cmVycm9yOiAlc1xuIixfX0ZVTkNUSU9OX18sc3RyZXJyb3IoZXJybm8pKTsNCisgICAgICAgDQorICAgICAgICAgICAgICAgIHBjbG9zZShwcDIpOy8vudix1bnctcANCisgICAgICAgICAgICAgICAgcmV0dXJuIDsgDQorICAgICAgICAgICAgfQ0KKyAgICAgICAgICAgIG1lbXNldChtYWNfdGltZSwwLDMzKTsNCisgICAgICAgICAgICBzdHJuY3B5KG1hY190aW1lLGJ1ZiwzMik7DQorICAgICAgICAgICANCisgICAgICAgICAgICBwcmludGYoIlslczolc11idWYwOiVzXG4iLF9fRklMRV9fLCBfX0ZVTkNUSU9OX18sIGJ1Zik7DQorICAgICAgICAgICANCisgICAgICAgICAgICBpZihOVUxMICE9IG1hY190aW1lKQ0KKyAgICAgICAgICAgIHsNCisgICAgICAgICAgICAgICAgc3RhX2xpc3QtPkVudHJ5W2ldLkNvbm5lY3RlZFRpbWUgPSBhdG9sKG1hY190aW1lKTsNCisgICAgICAgICAgICAgICAgcHJpbnRmKCJbJXM6JXNdQ29ubmVjdGVkVGltZS0+TnVtMzolZFxuIixfX0ZJTEVfXywgX19GVU5DVElPTl9fLCBzdGFfbGlzdC0+RW50cnlbaV0uQ29ubmVjdGVkVGltZSk7DQorICAgICAgICAgICAgfQ0KKyAgICAgICAgICAgIGVsc2UNCisgICAgICAgICAgICB7DQorICAgICAgICAgICAgICAgIHN0YV9saXN0LT5FbnRyeVtpXS5Db25uZWN0ZWRUaW1lID0gMDsNCisgICAgICAgICAgICB9DQorICAgICAgICAgICAgbWVtc2V0KGJ1ZiwgMCwgc2l6ZW9mKGJ1ZikpOyAgDQorICAgICAgICAgICAgcHJpbnRmKCJbJXM6JXNdbWFjX3RpbWU6JWRcbiIsX19GSUxFX18sIF9fRlVOQ1RJT05fXywgbWFjX3RpbWUpOw0KKyAgICAgICAgICAgIA0KKyAgICAgICAgfQ0KKyAgICAgICAgDQorICAgICAgcGNsb3NlKHBwMik7IC8vudix1bnctcANCisgICAgfQ0KKyAgICANCisgICAgKCpzdGFpb25saXN0KT0gKCpzdGFfbGlzdCk7DQorICAgIGlmKHN0YV9saXN0KSANCisgICAgew0KKyAgICAgICAgZnJlZShzdGFfbGlzdCk7IA0KKyAgICAgICAgc3RhX2xpc3Q9TlVMTDsNCisgICAgfQ0KKyAgICANCit9DQorDQorc3RhdGljIHZvaWQgd2xhbl9zZXRfY2hhbmdlX3NzaWRfa2V5X3N0YXR1cygpDQorew0KKwlpcGNfc2VuZF9tZXNzYWdlKE1PRFVMRV9JRF9XTEFOX1NFUlZFUiwgTU9EVUxFX0lEX1dJRkksIE1TR19DTURfTU9ESUZZX1NTSURfS0VZLCAwLCBOVUxMLCAwKTsNCit9DQorDQorc3RhdGljIGludCB6dGVfd2xhbl9zc2lkMV9iYXNpY19zZXQoY2hhciogc3NpZF9pbikNCit7DQorICAgIGNoYXIgICpzc2lkID0gTlVMTDsgDQorCWNoYXIgbnZfdG1wW1dJRklfU1NJRF9MRU5dID0gezB9Ow0KKwkNCisJaWYoTlVMTCA9PSBzc2lkX2luKQ0KKwl7DQorCQlwcmludGYoImlucHV0IHNzaWQgaXMgbnVsbFxuIik7DQorCQlyZXR1cm4gLTE7DQorCX0NCisNCisJaWYoKCFzdHJjbXAoc3NpZF9pbiwgIiAiKSkgfHwgKHN0cmxlbihzc2lkX2luKSA8PSAwKSB8fCAoc3RybGVuKHNzaWRfaW4pID4gV0lGSV9TU0lEX0xFTiApKQ0KKwl7DQorCQlwcmludGYoImlucHV0IHNzaWQgaXMgZXJyb3JcbiIpOw0KKwkJcmV0dXJuIC0xOw0KKwl9DQorICAgIC8vc3NpZA0KKyAgICBtZW1zZXQobnZfdG1wLDAsc2l6ZW9mKG52X3RtcCkpOw0KKyAgICBpZihzc2lkX2luICE9IE5VTEwpDQorICAgIHsgIA0KKyAgICAgICANCisgICAgICAgc2NfY2ZnX2dldCgiU1NJRDEiLG52X3RtcCxzaXplb2YobnZfdG1wKSk7DQorICAgICAgICBpZiAoMCAhPSBzdHJjbXAoc3NpZF9pbiwgbnZfdG1wKSkNCisgICAgICAgIHsNCisgICAgICAgICAgICBzY19jZmdfc2V0KCJTU0lEMSIsIHNzaWRfaW4pOw0KKwkJCS8vc2NfY2ZnX3NhdmUoKTsNCisJCQl3bGFuX3NldF9jaGFuZ2Vfc3NpZF9rZXlfc3RhdHVzKCk7DQorICAgICAgICB9DQorCQllbHNlDQorCQl7DQorCQkJcHJpbnRmKCJpbnB1dCBzc2lkIGlzIHNhbWUgXG4iKTsNCisJCQlyZXR1cm4gMTsNCisJCX0NCisgICAgfQ0KKyAgICByZXR1cm4gMDsNCit9DQorDQorc3RhdGljIGludCB6dGVfd2xhbl9zc2lkMV9zZWN1cml0eV9zZXQoY2hhciogcGFzc3dvcmQpDQorewkNCisgICAgY2hhciBhdXRoTW9kZVtXTEFOX1NFQ1VSSVRZX0xFTl0gICAgICA9IHswfTsNCisgICAgY2hhciBlbmNyeXBUeXBlW1dMQU5fRU5DUllUWVBFX0xFTl0gICA9IHswfTsNCisJY2hhciBEZWZhdWx0S2V5SURbV0xBTl9ERUZBVUxUSURfTEVOXSA9IHswfTsNCisgICANCisJc2NfY2ZnX2dldCgiQXV0aE1vZGUiLGF1dGhNb2RlLHNpemVvZihhdXRoTW9kZSkpOw0KKwlzY19jZmdfZ2V0KCJFbmNyeXBUeXBlIixlbmNyeXBUeXBlLHNpemVvZihlbmNyeXBUeXBlKSk7DQorDQorCQ0KKyAgICBpZihhdXRoTW9kZSAhPSBOVUxMICYmIGVuY3J5cFR5cGUgIT0gTlVMTCkNCisgICAgeyAgDQorICAgICAgICBwcmludGYoIndsYW5fc3NpZDFfc2VjdXJpdHlfc2V0IGF1dGhNb2RlID0gWyVzXVxuIiwgYXV0aE1vZGUpOw0KKwkJcHJpbnRmKCJ3bGFuX3NzaWQxX3NlY3VyaXR5X3NldCBlbmNyeXBUeXBlID0gWyVzXVxuIiwgZW5jcnlwVHlwZSk7ICAgDQorCQlpZihOVUxMID09IHBhc3N3b3JkICYmICghKCFzdHJjbXAoYXV0aE1vZGUsIFdGX0FVX09QRU4pICYmICFzdHJjbXAoZW5jcnlwVHlwZSwgV0ZfRU5DUllfTk9ORSkpKSkNCisJCXsNCisJCQlwcmludGYoIndsYW5fc3NpZDFfc2VjdXJpdHlfc2V0IHBhc3N3b3JkIGlzIG51bGxcbiIpOw0KKwkJCXJldHVybiAtMTsNCisJCX0NCisJCQ0KKyAgICAgICAgaWYoKCFzdHJjbXAoYXV0aE1vZGUsIFdGX0FVX09QRU4pKSAgfHwgKCFzdHJjbXAoYXV0aE1vZGUsIFdGX0FVX1NIQVJFKSkgfHwgICghc3RyY21wKGF1dGhNb2RlLCBXRl9BVV9XRVBBVVRPKSkpDQorICAgICAgICB7ICAgDQorICAgICAgICAgICAgaWYoKCghc3RyY21wKGF1dGhNb2RlLCBXRl9BVV9PUEVOKSkgJiYgKCFzdHJjbXAoYXV0aE1vZGUsIFdGX0VOQ1JZX1dFUCkpKSB8fA0KKyAgICAgICAgICAgIAkgKCFzdHJjbXAoYXV0aE1vZGUsIFdGX0FVX1NIQVJFKSkgfHwgKCFzdHJjbXAoYXV0aE1vZGUsIFdGX0FVX1dFUEFVVE8pKSkgDQorICAgICAgICAgICAgew0KKwkJCSAgICBpbnQgbGVuID0gMDsNCisJCQkJbGVuID0gc3RybGVuKHBhc3N3b3JkKTsNCisJCQkJaWYobGVuICE9IDUgfHwgbGVuICE9IDEwIHx8IGxlbiAhPSAxMyB8fCBsZW4gIT0gMjYpDQorCQkJCXsNCisJCQkJCXByaW50Zigid2xhbl9zc2lkMV9zZWN1cml0eV9zZXQgd2VwIHBzayBsZW4gPSBbJXNdXG4iLCBsZW4pOyAgDQorCQkJCQlyZXR1cm4gLTE7DQorCQkJCX0NCisJCQkJDQorCQkJCXNjX2NmZ19nZXQoIkRlZmF1bHRLZXlJRCIsRGVmYXVsdEtleUlELHNpemVvZihEZWZhdWx0S2V5SUQpKTsNCisgICAgICAgICAgICAgICAgaWYoRGVmYXVsdEtleUlEICE9IE5VTEwpDQorCQkJCXsNCisJCQkJCWNoYXIgb2xkX3dlcF9rZXlbV0xBTl9XRVBLRVlfTEVOXSA9IHswfTsNCisJCQkJCQ0KKwkJCQkJaWYoIXN0cmNtcChEZWZhdWx0S2V5SUQsICIxIikpDQorCQkJCQl7DQorCQkJCQkJc2NfY2ZnX2dldCgiS2V5MlN0cjEiLG9sZF93ZXBfa2V5LHNpemVvZihvbGRfd2VwX2tleSkpOw0KKwkJCQkJCWlmKHN0cmNtcChvbGRfd2VwX2tleSwgcGFzc3dvcmQpKQ0KKwkJCQkJCXsNCisJCQkJCQkJc2NfY2ZnX3NldCgiS2V5MlN0cjEiLCBwYXNzd29yZCk7DQorCQkJCQkJCS8vc2NfY2ZnX3NhdmUoKTsNCisJCQkJCQkJd2xhbl9zZXRfY2hhbmdlX3NzaWRfa2V5X3N0YXR1cygpOw0KKwkJCQkJCX0NCisJCQkJCQllbHNlDQorCQkJCQkJew0KKwkJCQkJCQlwcmludGYoIndsYW5fc3NpZDFfc2VjdXJpdHlfc2V0IHdlcCBwc2sgaXMgc2FtZVxuIik7ICANCisJCQkJCQkJcmV0dXJuIDE7DQorCQkJCQkJfQ0KKwkJCQkJfQ0KKwkJCQkJZWxzZSBpZighc3RyY21wKERlZmF1bHRLZXlJRCwgIjIiKSkNCisJCQkJCXsNCisJCQkJCQlzY19jZmdfZ2V0KCJLZXkzU3RyMSIsb2xkX3dlcF9rZXksc2l6ZW9mKG9sZF93ZXBfa2V5KSk7DQorCQkJCQkJaWYoc3RyY21wKG9sZF93ZXBfa2V5LCBwYXNzd29yZCkpDQorCQkJCQkJew0KKwkJCQkJCQlzY19jZmdfc2V0KCJLZXkzU3RyMSIsIHBhc3N3b3JkKTsNCisJCQkJCQkJLy9zY19jZmdfc2F2ZSgpOw0KKwkJCQkJCQl3bGFuX3NldF9jaGFuZ2Vfc3NpZF9rZXlfc3RhdHVzKCk7DQorCQkJCQkJfQ0KKwkJCQkJCWVsc2UNCisJCQkJCQl7DQorCQkJCQkJCXByaW50Zigid2xhbl9zc2lkMV9zZWN1cml0eV9zZXQgd2VwIHBzayBpcyBzYW1lXG4iKTsgIA0KKwkJCQkJCQlyZXR1cm4gMTsNCisJCQkJCQl9DQorCQkJCQl9DQorCQkJCQllbHNlIGlmKCFzdHJjbXAoRGVmYXVsdEtleUlELCAiMyIpKQ0KKwkJCQkJew0KKwkJCQkJCXNjX2NmZ19nZXQoIktleTRTdHIxIixvbGRfd2VwX2tleSxzaXplb2Yob2xkX3dlcF9rZXkpKTsNCisJCQkJCQlpZihzdHJjbXAob2xkX3dlcF9rZXksIHBhc3N3b3JkKSkNCisJCQkJCQl7DQorCQkJCQkJCXNjX2NmZ19zZXQoIktleTRTdHIxIiwgcGFzc3dvcmQpOw0KKwkJCQkJCQkvL3NjX2NmZ19zYXZlKCk7DQorCQkJCQkJCXdsYW5fc2V0X2NoYW5nZV9zc2lkX2tleV9zdGF0dXMoKTsNCisJCQkJCQl9DQorCQkJCQkJZWxzZQ0KKwkJCQkJCXsNCisJCQkJCQkJcHJpbnRmKCJ3bGFuX3NzaWQxX3NlY3VyaXR5X3NldCB3ZXAgcHNrIGlzIHNhbWVcbiIpOyAgDQorCQkJCQkJCXJldHVybiAxOw0KKwkJCQkJCX0NCisJCQkJCX0NCisJCQkJCWVsc2UgDQorCQkJCQl7DQorCQkJCQkJc2NfY2ZnX2dldCgiS2V5MVN0cjEiLG9sZF93ZXBfa2V5LHNpemVvZihvbGRfd2VwX2tleSkpOw0KKwkJCQkJCWlmKHN0cmNtcChvbGRfd2VwX2tleSwgcGFzc3dvcmQpKQ0KKwkJCQkJCXsNCisJCQkJCQkJc2NfY2ZnX3NldCgiS2V5MVN0cjEiLCBwYXNzd29yZCk7DQorCQkJCQkJCS8vc2NfY2ZnX3NhdmUoKTsNCisJCQkJCQkJd2xhbl9zZXRfY2hhbmdlX3NzaWRfa2V5X3N0YXR1cygpOw0KKwkJCQkJCX0NCisJCQkJCQllbHNlDQorCQkJCQkJew0KKwkJCQkJCQlwcmludGYoIndsYW5fc3NpZDFfc2VjdXJpdHlfc2V0IHdlcCBwc2sgaXMgc2FtZVxuIik7ICANCisJCQkJCQkJcmV0dXJuIDE7DQorCQkJCQkJfQ0KKwkJCQkJfQ0KKwkJCQl9DQorICAgICAgICAgICAgfQ0KKyAgICAgICAgICAgIGVsc2UgaWYoIXN0cmNtcChhdXRoTW9kZSwgV0ZfQVVfT1BFTikgJiYgIXN0cmNtcChlbmNyeXBUeXBlLCBXRl9FTkNSWV9OT05FKSkNCisgICAgICAgICAgICB7DQorICAgICAgICAgICAgICAgIHByaW50ZigiYXV0aE1vZGUgaXMgb3BlbiBhbmQgbm90IHdlcCBcbiIpOw0KKwkJCQl3bGFuX3NldF9jaGFuZ2Vfc3NpZF9rZXlfc3RhdHVzKCk7DQorCQkJCXJldHVybiAxOw0KKw0KKyAgICAgICAgICAgIH0NCisgICAgICAgIH0NCisgICAgICAgIGVsc2UgaWYoIXN0cmNtcChhdXRoTW9kZSwgV0ZfQVVfV1BBKSAgfHwgIXN0cmNtcChhdXRoTW9kZSwgV0ZfQVVfV1BBMikgfHwgIXN0cmNtcChhdXRoTW9kZSwgIFdGX0FVX1dQQV9XUEEyKSkNCisgICAgICAgIHsNCisJCQljaGFyIHBza1tXTEFOX1BTS19MRU5dICAgICAgICAgICAgICAgID0gezB9Ow0KKyAgICAgICAgICAgIGludCBsZW4gPSAwOw0KKwkJCWNoYXIgZW5jb2RlW1dMQU5fRU5DT0RFX1BTS19MRU5dID0gezB9Ow0KKwkJCWxlbiA9IHN0cmxlbihwYXNzd29yZCk7DQorCQkJDQorCQkJaWYobGVuIDwgOCB8fCBsZW4gPiA2NCkNCisJCQl7DQorCQkJCXByaW50ZigiJXMgcGFzc3dvcmQgbGVuIGlzICVkIFxuIixhdXRoTW9kZSwgbGVuKTsNCisJCQkJcmV0dXJuIC0xOw0KKwkJCX0NCisJCQkNCisJCQlzY19jZmdfZ2V0KCJXUEFQU0sxIixwc2ssc2l6ZW9mKHBzaykpOw0KKwkJCWlmKHBzayAhPSBOVUxMKQ0KKwkJCXsNCisJCQkJaWYoc3RyY21wKHBzaywgcGFzc3dvcmQpKQ0KKwkJCQl7DQorCQkJCQlzY19jZmdfc2V0KCJXUEFQU0sxIiwgcGFzc3dvcmQpOw0KKwkJCQkJYmFzZTY0X2VuY29kZShwYXNzd29yZCwgbGVuLCBlbmNvZGUsIFdMQU5fRU5DT0RFX1BTS19MRU4pOw0KKwkJCQkJc2NfY2ZnX3NldCgiV1BBUFNLMV9lbmNvZGUiLCBlbmNvZGUpOw0KKwkJCQkJLy9zY19jZmdfc2F2ZSgpOw0KKwkJCQkJd2xhbl9zZXRfY2hhbmdlX3NzaWRfa2V5X3N0YXR1cygpOw0KKwkJCQl9DQorCQkJfQ0KKyAgICAgICAgICAgIGVsc2UNCisJCQl7DQorCQkJCXNjX2NmZ19zZXQoIldQQVBTSzEiLCBwYXNzd29yZCk7DQorCQkJCWJhc2U2NF9lbmNvZGUocGFzc3dvcmQsIGxlbiwgZW5jb2RlLCBXTEFOX0VOQ09ERV9QU0tfTEVOKTsNCisJCQkJc2NfY2ZnX3NldCgiV1BBUFNLMV9lbmNvZGUiLCBlbmNvZGUpOw0KKwkJCQkvL3NjX2NmZ19zYXZlKCk7DQorCQkJCXdsYW5fc2V0X2NoYW5nZV9zc2lkX2tleV9zdGF0dXMoKTsNCisJCQl9DQorICAgICAgICB9DQorCQllbHNlIGlmKCFzdHJjbXAoYXV0aE1vZGUsIFdGX0FVX1dBUElQU0spKQ0KKwkJew0KKwkJCWNoYXIgcHNrW1dMQU5fUFNLX0xFTl0gICAgICAgICAgICAgICAgPSB7MH07DQorCQkJaW50IGxlbiA9IDA7DQorCQkJY2hhciBlbmNvZGVbV0xBTl9QU0tfTEVOXSA9IHswfTsNCisJCQlsZW4gPSBzdHJsZW4ocGFzc3dvcmQpOw0KKwkJCQ0KKwkJCWlmKGxlbiA8IDggfHwgbGVuID4gNjQpDQorCQkJew0KKwkJCQlwcmludGYoIldGX0FVX1dBUElQU0sgcGFzc3dvcmQgbGVuIGlzICVkIFxuIiwgbGVuKTsNCisJCQkJcmV0dXJuIC0xOw0KKwkJCX0NCisJCQkNCisJCQlzY19jZmdfZ2V0KCJXUEFQU0sxIixwc2ssc2l6ZW9mKHBzaykpOw0KKwkJCWlmKHBzayAhPSBOVUxMKQ0KKwkJCXsNCisJCQkJaWYoc3RyY21wKHBzaywgcGFzc3dvcmQpKQ0KKwkJCQl7DQorCQkJCQlzY19jZmdfc2V0KCJXUEFQU0sxIiwgcGFzc3dvcmQpOw0KKwkJCQkJYmFzZTY0X2VuY29kZShwYXNzd29yZCwgbGVuLCBlbmNvZGUsIFdMQU5fRU5DT0RFX1BTS19MRU4pOw0KKwkJCQkJc2NfY2ZnX3NldCgiV1BBUFNLMV9lbmNvZGUiLCBlbmNvZGUpOw0KKwkJCQkJLy9zY19jZmdfc2F2ZSgpOw0KKwkJCQkJd2xhbl9zZXRfY2hhbmdlX3NzaWRfa2V5X3N0YXR1cygpOw0KKwkJCQl9DQorCQkJfQ0KKyAgICAgICAgICAgIGVsc2UNCisJCQl7DQorCQkJCXNjX2NmZ19zZXQoIldQQVBTSzEiLCBwYXNzd29yZCk7DQorCQkJCWJhc2U2NF9lbmNvZGUocGFzc3dvcmQsIGxlbiwgZW5jb2RlLCBXTEFOX0VOQ09ERV9QU0tfTEVOKTsNCisJCQkJc2NfY2ZnX3NldCgiV1BBUFNLMV9lbmNvZGUiLCBlbmNvZGUpOw0KKwkJCQkvL3NjX2NmZ19zYXZlKCk7DQorCQkJCXdsYW5fc2V0X2NoYW5nZV9zc2lkX2tleV9zdGF0dXMoKTsNCisJCQl9DQorCQl9DQorICAgICAgICBlbHNlDQorICAgICAgICB7DQorICAgICAgICAgICAgLy8gb3RoZXIgc2VjdXJpdHkgbW9kZSBpcyBpbnZhbGlkDQorICAgICAgICAgICAgcHJpbnRmKCJFUlJPUjpzZWN1cml0eSBtb2RlICBpcyBpbnZhbGlkXG4iKTsNCisgICAgICAgICAgICByZXR1cm4gLTE7DQorICAgICAgICB9DQorICAgIH0NCisgICAgZWxzZQ0KKyAgICB7DQorICAgICAgICAvL3NlY3VyaXR5X21vZGUgaXMgTlVMTA0KKyAgICAgICAgcHJpbnRmKCJFUlJPUjpzZWN1cml0eV9tb2RlIGlzIG51bGxcbiIpOw0KKyAgICAgICAgcmV0dXJuIC0xOw0KKyAgICB9DQorDQorICAgIHJldHVybiAwOw0KK30NCisNCitpbnQgenRlX3dsYW5fZ2V0X3NzaWQxX3NldHRpbmdzKGNoYXIqIHNzaWQsIGNoYXIqIHBhc3N3b3JkLCBpbnQgc3NpZF9sZW4sIGludCBwYXNzd29yZF9sZW4pDQorew0KKwljaGFyIGF1dGhNb2RlW1dMQU5fU0VDVVJJVFlfTEVOXSAgICAgID0gezB9Ow0KKyAgICBjaGFyIGVuY3J5cFR5cGVbV0xBTl9FTkNSWVRZUEVfTEVOXSAgID0gezB9Ow0KKwljaGFyIERlZmF1bHRLZXlJRFtXTEFOX0RFRkFVTFRJRF9MRU5dID0gezB9Ow0KKw0KKwlpZihOVUxMID09IHNzaWQgfHwgTlVMTCA9PSBwYXNzd29yZCkNCisJew0KKwkJcHJpbnRmKCJFUlJPUjppbnB1dCBzc2lkICYmIHBhc3N3b3JkIGlzIG51bGxcbiIpOw0KKwkJcmV0dXJuIC0xOw0KKwl9DQorCQ0KKwlpZihOVUxMICE9IHNzaWQpDQorCXsNCisJCWNoYXIgb2xkX3NzaWRbV0lGSV9TU0lEX0xFTl0gPSB7MH07DQorCQlzY19jZmdfZ2V0KCJTU0lEMSIsb2xkX3NzaWQsc2l6ZW9mKG9sZF9zc2lkKSk7DQorCQlpZihvbGRfc3NpZCAhPSBOVUxMKQ0KKwkJew0KKwkJCXN0cm5jcHkoc3NpZCwgb2xkX3NzaWQsIHNzaWRfbGVuIC0gMSk7DQorCQl9DQorCQllbHNlDQorCQl7DQorCQkJcHJpbnRmKCJFUlJPUjppbnB1dCBvbGRfc3NpZCBpcyBudWxsXG4iKTsNCisJCQlyZXR1cm4gLTE7DQorCQl9DQorCX0NCisJDQorCWlmKE5VTEwgIT0gcGFzc3dvcmQpDQorCXsJCQ0KKwkJc2NfY2ZnX2dldCgiQXV0aE1vZGUiLGF1dGhNb2RlLHNpemVvZihhdXRoTW9kZSkpOw0KKwkJc2NfY2ZnX2dldCgiRW5jcnlwVHlwZSIsZW5jcnlwVHlwZSxzaXplb2YoZW5jcnlwVHlwZSkpOw0KKw0KKwkJDQorCQlpZihhdXRoTW9kZSAhPSBOVUxMICYmIGVuY3J5cFR5cGUgIT0gTlVMTCkNCisJCXsgIA0KKwkJCXByaW50Zigid2xhbl9zc2lkMV9zZWN1cml0eV9nZXQgYXV0aE1vZGUgPSBbJXNdXG4iLCBhdXRoTW9kZSk7ICAgDQorCQkJcHJpbnRmKCJ3bGFuX3NzaWQxX3NlY3VyaXR5X2dldCBlbmNyeXBUeXBlID0gWyVzXVxuIiwgZW5jcnlwVHlwZSk7ICAgDQorDQorCQkJaWYoKCFzdHJjbXAoYXV0aE1vZGUsIFdGX0FVX09QRU4pKSAgfHwgKCFzdHJjbXAoYXV0aE1vZGUsIFdGX0FVX1NIQVJFKSkgfHwgICghc3RyY21wKGF1dGhNb2RlLCBXRl9BVV9XRVBBVVRPKSkpDQorCQkJeyAgIA0KKwkJCQlpZigoKCFzdHJjbXAoYXV0aE1vZGUsIFdGX0FVX09QRU4pKSAmJiAoIXN0cmNtcChhdXRoTW9kZSwgV0ZfRU5DUllfV0VQKSkpIHx8DQorCQkJCQkoIXN0cmNtcChhdXRoTW9kZSwgV0ZfQVVfU0hBUkUpKSB8fCAoIXN0cmNtcChhdXRoTW9kZSwgV0ZfQVVfV0VQQVVUTykpKSANCisJCQkJew0KKwkJCQkJc2NfY2ZnX2dldCgiRGVmYXVsdEtleUlEIixEZWZhdWx0S2V5SUQsc2l6ZW9mKERlZmF1bHRLZXlJRCkpOw0KKwkJCQkJaWYoRGVmYXVsdEtleUlEICE9IE5VTEwpDQorCQkJCQl7DQorCQkJCQkJY2hhciBvbGRfd2VwX2tleVtXTEFOX1dFUEtFWV9MRU5dID0gezB9Ow0KKwkJCQkJCWlmKCFzdHJjbXAoRGVmYXVsdEtleUlELCAiMSIpKQ0KKwkJCQkJCXsNCisJCQkJCQkJc2NfY2ZnX2dldCgiS2V5MlN0cjEiLG9sZF93ZXBfa2V5LHNpemVvZihvbGRfd2VwX2tleSkpOw0KKwkJCQkJCQlpZihvbGRfd2VwX2tleSAhPSBOVUxMKQ0KKwkJCQkJCQl7DQorCQkJCQkJCQlzdHJuY3B5KHBhc3N3b3JkLCBvbGRfd2VwX2tleSwgcGFzc3dvcmRfbGVuLTEpOw0KKwkJCQkJCQl9DQorCQkJCQkJCWVsc2UNCisJCQkJCQkJew0KKwkJCQkJCQkJcHJpbnRmKCJFUlJPUjppbnB1dCBvbGRfd2VwX2tleSBpcyBudWxsXG4iKTsNCisJCQkJCQkJCXJldHVybiAtMTsNCisJCQkJCQkJfQ0KKwkJCQkJCX0NCisJCQkJCQllbHNlIGlmKCFzdHJjbXAoRGVmYXVsdEtleUlELCAiMiIpKQ0KKwkJCQkJCXsNCisJCQkJCQkJc2NfY2ZnX2dldCgiS2V5M1N0cjEiLG9sZF93ZXBfa2V5LHNpemVvZihvbGRfd2VwX2tleSkpOw0KKwkJCQkJCQlpZihvbGRfd2VwX2tleSAhPSBOVUxMKQ0KKwkJCQkJCQl7DQorCQkJCQkJCQlzdHJuY3B5KHBhc3N3b3JkLCBvbGRfd2VwX2tleSwgcGFzc3dvcmRfbGVuLTEpOw0KKwkJCQkJCQl9DQorCQkJCQkJCWVsc2UNCisJCQkJCQkJew0KKwkJCQkJCQkJcHJpbnRmKCJFUlJPUjppbnB1dCBvbGRfd2VwX2tleSBpcyBudWxsXG4iKTsNCisJCQkJCQkJCXJldHVybiAtMTsNCisJCQkJCQkJfQ0KKwkJCQkJCX0NCisJCQkJCQllbHNlIGlmKCFzdHJjbXAoRGVmYXVsdEtleUlELCAiMyIpKQ0KKwkJCQkJCXsNCisJCQkJCQkJc2NfY2ZnX2dldCgiS2V5NFN0cjEiLG9sZF93ZXBfa2V5LHNpemVvZihvbGRfd2VwX2tleSkpOw0KKwkJCQkJCQlpZihvbGRfd2VwX2tleSAhPSBOVUxMKQ0KKwkJCQkJCQl7DQorCQkJCQkJCQlzdHJuY3B5KHBhc3N3b3JkLCBvbGRfd2VwX2tleSwgcGFzc3dvcmRfbGVuLTEpOw0KKwkJCQkJCQl9DQorCQkJCQkJCWVsc2UNCisJCQkJCQkJew0KKwkJCQkJCQkJcHJpbnRmKCJFUlJPUjppbnB1dCBvbGRfd2VwX2tleSBpcyBudWxsXG4iKTsNCisJCQkJCQkJCXJldHVybiAtMTsNCisJCQkJCQkJfQ0KKwkJCQkJCX0NCisJCQkJCQllbHNlIA0KKwkJCQkJCXsNCisJCQkJCQkJc2NfY2ZnX2dldCgiS2V5MVN0cjEiLG9sZF93ZXBfa2V5LHNpemVvZihvbGRfd2VwX2tleSkpOw0KKwkJCQkJCQlpZihvbGRfd2VwX2tleSAhPSBOVUxMKQ0KKwkJCQkJCQl7DQorCQkJCQkJCQlzdHJuY3B5KHBhc3N3b3JkLCBvbGRfd2VwX2tleSwgcGFzc3dvcmRfbGVuLTEpOw0KKwkJCQkJCQl9DQorCQkJCQkJCWVsc2UNCisJCQkJCQkJew0KKwkJCQkJCQkJcHJpbnRmKCJFUlJPUjppbnB1dCBvbGRfd2VwX2tleSBpcyBudWxsXG4iKTsNCisJCQkJCQkJCXJldHVybiAtMTsNCisJCQkJCQkJfQ0KKwkJCQkJCX0NCisJCQkJCX0NCisJCQkJfQ0KKyAgICAgICAgICAgIH0NCisJCQllbHNlIGlmKCFzdHJjbXAoYXV0aE1vZGUsIFdGX0FVX1dQQSkgIHx8ICFzdHJjbXAoYXV0aE1vZGUsIFdGX0FVX1dQQTIpIHx8ICFzdHJjbXAoYXV0aE1vZGUsICBXRl9BVV9XUEFfV1BBMikpDQorCQkJew0KKwkJCQljaGFyIHBza1tXTEFOX1BTS19MRU5dID0gezB9Ow0KKwkJCQlzY19jZmdfZ2V0KCJXUEFQU0sxIixwc2ssc2l6ZW9mKHBzaykpOw0KKwkJCQlpZihwc2sgIT0gTlVMTCkNCisJCQkJew0KKwkJCQkJc3RybmNweShwYXNzd29yZCwgcHNrLCBwYXNzd29yZF9sZW4tMSk7DQorCQkJCX0NCisJCQkJZWxzZQ0KKwkJCQl7DQorCQkJCQlwcmludGYoIkVSUk9SOiVzIGlucHV0IHBzayBpcyBudWxsXG4iLCBhdXRoTW9kZSk7DQorCQkJCQlyZXR1cm4gLTE7DQorCQkJCX0NCisJCQl9DQorCQkJZWxzZSBpZighc3RyY21wKGF1dGhNb2RlLCBXRl9BVV9XQVBJUFNLKSkNCisJCQl7DQorCQkJCWNoYXIgcHNrW1dMQU5fUFNLX0xFTl0gICAgICAgICAgICAgICAgPSB7MH07DQorCQkJCXNjX2NmZ19nZXQoIldQQVBTSzEiLHBzayxzaXplb2YocHNrKSk7DQorCQkJCWlmKHBzayAhPSBOVUxMKQ0KKwkJCQl7DQorCQkJCQlzdHJuY3B5KHBhc3N3b3JkLCBwc2ssIHBhc3N3b3JkX2xlbi0xKTsNCisJCQkJfQ0KKwkJCQllbHNlDQorCQkJCXsNCisJCQkJCXByaW50ZigiRVJST1I6JXMgaW5wdXQgcHNrIGlzIG51bGxcbiIsIGF1dGhNb2RlKTsNCisJCQkJCXJldHVybiAtMTsNCisJCQkJfQ0KKwkJCX0NCisJCQllbHNlDQorCQkJew0KKwkJCQlyZXR1cm4gLTE7DQorCQkJfQ0KKwkJfQ0KKwkJZWxzZQ0KKwkJew0KKwkJCXJldHVybiAtMTsNCisJCX0NCisgICAgfQ0KKwlyZXR1cm4gMDsNCit9DQorDQoraW50IHp0ZV93bGFuX3NzaWQxX3NldChjaGFyKiBzc2lkLCBjaGFyKiBwYXNzd29yZCkNCit7DQorCWludCByZXRfZm9yX2Jhc2ljID0gMDsNCisJaW50IHJldF9mb3Jfc2VjdXJpdHkgPSAwOw0KKwkNCisJcmV0X2Zvcl9iYXNpYyA9IHp0ZV93bGFuX3NzaWQxX2Jhc2ljX3NldChzc2lkKTsNCisgICAgaWYoLTEgPT0gcmV0X2Zvcl9iYXNpYykNCisgICAgew0KKyAgICAgICAgcHJpbnRmKCJ3bGFuX3NzaWQxX2Jhc2ljX3NldCBpcyBmYWxzZVxuIik7DQorICAgICAgICByZXR1cm4gLTE7DQorICAgIH0NCisJcmV0X2Zvcl9zZWN1cml0eSA9IHp0ZV93bGFuX3NzaWQxX3NlY3VyaXR5X3NldChwYXNzd29yZCk7DQorICAgIGlmKC0xID09IHJldF9mb3Jfc2VjdXJpdHkpDQorICAgIHsNCisgICAgICAgIHByaW50ZigiY2FsbCBsYW5fc3NpZDFfc2VjdXJpdHlfc2V0IGZhaWx1cmUgLlxuIik7ICAgDQorICAgICAgICByZXR1cm4gLTE7DQorICAgIH0NCisJDQorICAgIGlmKHJldF9mb3JfYmFzaWMgPT0gMCB8fCByZXRfZm9yX3NlY3VyaXR5ID09IDApDQorCXsNCisJCWlmKDAgPT0gaXBjX3NlbmRfbWVzc2FnZShNT0RVTEVfSURfV0xBTl9TRVJWRVIsIE1PRFVMRV9JRF9XSUZJLCBNU0dfQ01EX1dJRklfQURWQU5DRUQsIDIsICIxIiwgMCkpDQorCQl7IA0KKwkJCXNjX2NmZ19zZXQoIlJhZGlvT2ZmIiwgIjAiKTsNCisJCQlwcmludGYoIndpZmkgc2V0IGNtZCBkb25lIVxuIik7DQorCQl9DQorCQllbHNlDQorCQl7DQorCQkJcHJpbnRmKCJ3aWZpIHNldCBjbWQgd2xhbl9zc2lkMV9zZXQgZXJyb3IhXG4iKTsNCisJCQlyZXR1cm4gLTE7DQorCQl9DQorICAgIH0NCisgICAgcmV0dXJuIDA7IA0KK30NCisNCisNCitpbnQgenRlX3dsYW5fY2FwdHVyZV9zdGFfbnVtKCkNCit7DQorICAgIGludCB0b3RhbF9zdGF0aW9uX251bSA9IDA7DQorICAgIEZJTEUgKnBwID0gTlVMTDsNCisgICAgY2hhciAqdG1wID0gTlVMTDsNCisgICAgY2hhciBidWZbMTI4XT17MH07DQorICAgIGNoYXIgYXV0aG1vZGVbMjBdPXswfTsNCisJY2hhciByYWRpb19vZmZbMjBdID0gezB9Ow0KKyAgICBjaGFyIHdpZmlfc3RhX2Nvbm5lY3Rpb25bOF09ezB9Ow0KKyAgICBjaGFyIGNtZFsxMjhdPXswfTsNCisgICAgY2hhciBpaWZuYW1lWzE2XT17MH07DQorCQ0KKyAgICBzY19jZmdfZ2V0KCJSYWRpb09mZiIscmFkaW9fb2ZmLHNpemVvZihyYWRpb19vZmYpKTsNCisgICAgc2NfY2ZnX2dldCgid2lmaV9zdGFfY29ubmVjdGlvbiIsIHdpZmlfc3RhX2Nvbm5lY3Rpb24sIHNpemVvZih3aWZpX3N0YV9jb25uZWN0aW9uKSk7DQorICAgIHNjX2NmZ19nZXQoIkF1dGhNb2RlIixhdXRobW9kZSwgMjApOw0KKwkNCisJaWYgKCFzdHJuY21wKHJhZGlvX29mZiwgIjAiLCAxKSkNCisJew0KKwkgICAgcHJpbnRmKCJbd2xhbi1pbnRlcmZhY2VdYXAtc2VydmljZSBzdG9wcGVkISByZXR1cm4hXG4iKTsNCisJICAgIHJldHVybiAwOw0KKwl9DQorICAgIA0KKyAgICBpZihzdHJuY21wKHdpZmlfc3RhX2Nvbm5lY3Rpb24sICIxIiwxKSA9PSAwKQ0KKwl7DQorCQlzdHJjcHkoaWlmbmFtZSwiLWkgd2wwLjEiKTsNCisJfQ0KKyAgICBlbHNlDQorCXsNCisJCXN0cmNweShpaWZuYW1lLCItaSB3bGFuMCIpOw0KKwl9DQorDQorICAgIGlmKCghc3RyY21wKGF1dGhtb2RlLCJXUEFQU0siKSl8fCghc3RyY21wKGF1dGhtb2RlLCJXUEEyUFNLIikpfHwoIXN0cmNtcChhdXRobW9kZSwiV1BBUFNLV1BBMlBTSyIpKSkNCisJew0KKwkJc3ByaW50ZihjbWQsICJ3bCAlcyBhdXRob19zdGFfbGlzdCIsIGlpZm5hbWUpOw0KKwkJc3ByaW50ZihjbWQsICJ3bCAlcyBhdXRob19zdGFfbGlzdCIsIGlpZm5hbWUpOw0KKwl9DQorCWVsc2UNCisJew0KKwkJc3ByaW50ZihjbWQsICJ3bCAlcyAgYXNzb2NsaXN0IiwgaWlmbmFtZSk7DQorCX0NCisNCisgICAgaWYgKCBjbWQgPT0gTlVMTCApDQorCXsNCisJICAgIHByaW50ZigiW3dsYW4taW50ZXJmYWNlXWVycm9yISEgY21kIGlzIE5VTEwhIVxuIik7DQorCSAgICByZXR1cm4gMDsNCisJfQ0KKw0KKyAgICBwcCA9IHBvcGVuKGNtZCwgInIiKTsgLy9waXBlIHN0YXJ0cw0KKyAgICBpZiAoIXBwKQ0KKyAgICB7DQorICAgICAgICBwcmludGYoIlt3bGFuLWludGVyZmFjZV1lcnJvciEhIGNyZWF0ZSBwaXBlIGZhaWxlZCEhXG4iKTsNCisgICAgICAgIHJldHVybiAwOw0KKyAgICB9DQorDQorICAgIHN0cmNweShidWYsIkFCTk9STUFMIik7DQorICAgIA0KK0FnYWluOg0KKyAgICB3aGlsZShmZ2V0cyhidWYsIDEyOCwgcHApICE9IE5VTEwpICAgDQorCXsgICAgICANCisgICAgICAgIGlmKHN0cmNtcChidWYsIkFCTk9STUFMIik9PTApICAvL2ZnZXRzIGVycm9yIA0KKyAgICAgICAgew0KKyAgICAgICAgICAgIHByaW50ZigiW3dsYW4taW50ZXJmYWNlXWVycm9yISEgWyVzXSBzdHJlcnJvcjogJXNcbiIsX19GVU5DVElPTl9fLHN0cmVycm9yKGVycm5vKSk7DQorICAgICAgICAgICAgaWYoZXJybm8gPT0gRUlOVFIpIC8vSW50ZXJydXB0ZWQgc3lzdGVtIGNhbGwsdHJ5IGFnYWluDQorICAgICAgICAgICAgew0KKyAgICAgICAgICAgICAgICBnb3RvIEFnYWluOw0KKyAgICAgICAgICAgIH0NCisgICAgICAgICAgICANCisgICAgICAgICAgICBwY2xvc2UocHApOy8vY2xvc2UgcGlwZQ0KKyAgICAgICAgICAgIHJldHVybiAwOyANCisgICAgICAgIH0NCisNCisgICAgICAgIGlmKHN0cmxlbihidWYpID4gMCkNCisgICAgICAgIHsNCisJCSAgICBpZigodG1wID0gc3Ryc3RyKGJ1ZiwgIjoiKSkgIT0gTlVMTCkgICAgICAgICAgICANCisJCSAgICB7ICAgICAgICAgICAgICAgIA0KKwkJICAgICAgdG90YWxfc3RhdGlvbl9udW0gKz0gMTsgICAgICAgICAgICANCisJCSAgICB9ICANCisgICAgICAgIH0NCisgICAgICAgIG1lbXNldChidWYsMCwxMjgpOw0KKyAgICAgICAgc3RyY3B5KGJ1ZiwiQUJOT1JNQUwiKTsNCisgICAgICAgIAkgCQkNCisJfSAgICANCisJDQorICAgIHBjbG9zZShwcCk7Ly9jbG9zZSBwaXBlDQorICAgIHByaW50ZigiW3dsYW4taW50ZXJmYWNlXSB0b3RhbF9zdGF0aW9uX251bT0lZFxuIix0b3RhbF9zdGF0aW9uX251bSk7DQorICAgIHJldHVybiB0b3RhbF9zdGF0aW9uX251bTsNCit9DQorDQorDQordm9pZCB6dGVfZ2V0X3dpZmlfc3RhX2xpc3QoUlRfODAyXzExX01BQ19UQUJMRSAqc3RhTGlzdCkNCit7DQorICANCisgICAgICAgICBpbnQgaSA9IDA7DQorCWNoYXIgc3RhdGlvbl9tYWNbMTgqMzJdPXswfTsgLy8gMDA6MDA6MDA6MDA6MDA6MDA7DQorCWNoYXIgc3RhdGlvbl9tYWNfdG1wWzE4KjMyXT17MH07DQorCWNoYXIgdG1wX3N0clsxMF0gPSB7MH07DQorDQorICAgICAgIGlmKE5VTEwgPT0gc3RhTGlzdCkNCisgICAgew0KKyAgICAgICAgcmV0dXJuOw0KKyAgICB9DQorICAgIHp0ZV93bGFuX2dldF93aWZpX3N0YXRpb25fbGlzdChzdGFMaXN0KTsNCisJDQorICAgIHByaW50ZigiWyVzOiVzXXN0YUxpc3QtPk51bTE6JWRcbiIsX19GSUxFX18sIF9fRlVOQ1RJT05fXywgc3RhTGlzdC0+TnVtKTsNCisgICAgcHJpbnRmKCJbJXM6JXNdc3RhTGlzdC0+Q29ubmVjdGVkVGltZTolZFxuIixfX0ZJTEVfXywgX19GVU5DVElPTl9fLCBzdGFMaXN0LT5FbnRyeVswXS5Db25uZWN0ZWRUaW1lKTsNCisNCisgICAgc3ByaW50Zih0bXBfc3RyLCAiJWQiLCBzdGFMaXN0LT5OdW0pOwkNCisJc2NfY2ZnX3NldCgid2lmaWNvdW50IiwgdG1wX3N0cik7DQorCXNjX2NmZ19zZXQoInN0YXRpb25fbnVtIiwgdG1wX3N0cik7DQorICAgIGZvcihpPTA7IGk8c3RhTGlzdC0+TnVtOyBpKyspDQorICAgIHsNCisgICAgICAgIHNwcmludGYoc3RhdGlvbl9tYWMgKyBpICogMTgsICIlMi4yWDolMi4yWDolMi4yWDolMi4yWDolMi4yWDolMi4yWDsiLFwNCisJICAgCSAgICAgICAgICAgc3RhTGlzdC0+RW50cnlbaV0uQWRkclswXSwgc3RhTGlzdC0+RW50cnlbaV0uQWRkclsxXSwNCisJCQkJICAgIHN0YUxpc3QtPkVudHJ5W2ldLkFkZHJbMl0sIHN0YUxpc3QtPkVudHJ5W2ldLkFkZHJbM10sDQorCQkJCSAgICBzdGFMaXN0LT5FbnRyeVtpXS5BZGRyWzRdLCBzdGFMaXN0LT5FbnRyeVtpXS5BZGRyWzVdKTsNCisgICAgfQ0KKwlpZihzdGFMaXN0LT5OdW0gIT0gMCkNCisJew0KKwkJc3RybmNweShzdGF0aW9uX21hY190bXAsIHN0YXRpb25fbWFjLCBzdHJsZW4oc3RhdGlvbl9tYWMpIC0gMSk7DQorCX0NCisJDQorCXNjX2NmZ19zZXQoInN0YXRpb25fbWFjIiwgc3RhdGlvbl9tYWNfdG1wKTsgICANCisJDQorfQ0KKw0KKyNpZiAwIC8va3cgMw0KK2ludCBnZXRfY2hhbm5lbCgpDQorew0KKwljaGFyIGNoYW5uZWxbOF09ezB9Ow0KKwlwaXBlY21kKCJ3bCBjaGFubmVsIHwgZ3JlcCBtYWMgfGN1dCAtZjIiLCBjaGFubmVsKTsNCisJcmV0dXJuIGF0b2koY2hhbm5lbCk7DQorfQ0KKyNlbmRpZg0K