LyoKICogc25tcGRmLmMgLSBzZW5kIHNubXAgR0VUIHJlcXVlc3RzIHRvIGEgbmV0d29yayBlbnRpdHkuCiAqCiAqLwoKLyogUG9ydGlvbnMgb2YgdGhpcyBmaWxlIGFyZSBzdWJqZWN0IHRvIHRoZSBmb2xsb3dpbmcgY29weXJpZ2h0KHMpLiAgU2VlCiAqIHRoZSBOZXQtU05NUCdzIENPUFlJTkcgZmlsZSBmb3IgbW9yZSBkZXRhaWxzIGFuZCBvdGhlciBjb3B5cmlnaHRzCiAqIHRoYXQgbWF5IGFwcGx5OgogKi8KLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCglDb3B5cmlnaHQgMTk4OCwgMTk4OSwgMTk5MSwgMTk5MiBieSBDYXJuZWdpZSBNZWxsb24gVW5pdmVyc2l0eQoKICAgICAgICAgICAgICAgICAgICAgIEFsbCBSaWdodHMgUmVzZXJ2ZWQKClBlcm1pc3Npb24gdG8gdXNlLCBjb3B5LCBtb2RpZnksIGFuZCBkaXN0cmlidXRlIHRoaXMgc29mdHdhcmUgYW5kIGl0cyAKZG9jdW1lbnRhdGlvbiBmb3IgYW55IHB1cnBvc2UgYW5kIHdpdGhvdXQgZmVlIGlzIGhlcmVieSBncmFudGVkLCAKcHJvdmlkZWQgdGhhdCB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSBhcHBlYXIgaW4gYWxsIGNvcGllcyBhbmQgdGhhdApib3RoIHRoYXQgY29weXJpZ2h0IG5vdGljZSBhbmQgdGhpcyBwZXJtaXNzaW9uIG5vdGljZSBhcHBlYXIgaW4gCnN1cHBvcnRpbmcgZG9jdW1lbnRhdGlvbiwgYW5kIHRoYXQgdGhlIG5hbWUgb2YgQ01VIG5vdCBiZQp1c2VkIGluIGFkdmVydGlzaW5nIG9yIHB1YmxpY2l0eSBwZXJ0YWluaW5nIHRvIGRpc3RyaWJ1dGlvbiBvZiB0aGUKc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYywgd3JpdHRlbiBwcmlvciBwZXJtaXNzaW9uLiAgCgpDTVUgRElTQ0xBSU1TIEFMTCBXQVJSQU5USUVTIFdJVEggUkVHQVJEIFRPIFRISVMgU09GVFdBUkUsIElOQ0xVRElORwpBTEwgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUywgSU4gTk8gRVZFTlQgU0hBTEwKQ01VIEJFIExJQUJMRSBGT1IgQU5ZIFNQRUNJQUwsIElORElSRUNUIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyBPUgpBTlkgREFNQUdFUyBXSEFUU09FVkVSIFJFU1VMVElORyBGUk9NIExPU1MgT0YgVVNFLCBEQVRBIE9SIFBST0ZJVFMsCldIRVRIRVIgSU4gQU4gQUNUSU9OIE9GIENPTlRSQUNULCBORUdMSUdFTkNFIE9SIE9USEVSIFRPUlRJT1VTIEFDVElPTiwKQVJJU0lORyBPVVQgT0YgT1IgSU4gQ09OTkVDVElPTiBXSVRIIFRIRSBVU0UgT1IgUEVSRk9STUFOQ0UgT0YgVEhJUwpTT0ZUV0FSRS4KKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwovKgogKiBQb3J0aW9ucyBvZiB0aGlzIGZpbGUgYXJlIGNvcHlyaWdodGVkIGJ5OgogKiBDb3B5cmlnaHQgqSAyMDAzIFN1biBNaWNyb3N5c3RlbXMsIEluYy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KICogVXNlIGlzIHN1YmplY3QgdG8gbGljZW5zZSB0ZXJtcyBzcGVjaWZpZWQgaW4gdGhlIENPUFlJTkcgZmlsZQogKiBkaXN0cmlidXRlZCB3aXRoIHRoZSBOZXQtU05NUCBwYWNrYWdlLgogKi8KI2luY2x1ZGUgPG5ldC1zbm1wL25ldC1zbm1wLWNvbmZpZy5oPgoKI2lmIEhBVkVfU1RETElCX0gKI2luY2x1ZGUgPHN0ZGxpYi5oPgojZW5kaWYKI2lmIEhBVkVfVU5JU1REX0gKI2luY2x1ZGUgPHVuaXN0ZC5oPgojZW5kaWYKI2lmIEhBVkVfU1RSSU5HX0gKI2luY2x1ZGUgPHN0cmluZy5oPgojZWxzZQojaW5jbHVkZSA8c3RyaW5ncy5oPgojZW5kaWYKI2luY2x1ZGUgPHN5cy90eXBlcy5oPgojaWYgSEFWRV9ORVRJTkVUX0lOX0gKI2luY2x1ZGUgPG5ldGluZXQvaW4uaD4KI2VuZGlmCiNpbmNsdWRlIDxzdGRpby5oPgojaW5jbHVkZSA8Y3R5cGUuaD4KI2lmIFRJTUVfV0lUSF9TWVNfVElNRQojIGlmZGVmIFdJTjMyCiMgIGluY2x1ZGUgPHN5cy90aW1lYi5oPgojIGVsc2UKIyAgaW5jbHVkZSA8c3lzL3RpbWUuaD4KIyBlbmRpZgojIGluY2x1ZGUgPHRpbWUuaD4KI2Vsc2UKIyBpZiBIQVZFX1NZU19USU1FX0gKIyAgaW5jbHVkZSA8c3lzL3RpbWUuaD4KIyBlbHNlCiMgIGluY2x1ZGUgPHRpbWUuaD4KIyBlbmRpZgojZW5kaWYKI2lmIEhBVkVfU1lTX1NFTEVDVF9ICiNpbmNsdWRlIDxzeXMvc2VsZWN0Lmg+CiNlbmRpZgojaWYgSEFWRV9XSU5TT0NLX0gKI2luY2x1ZGUgPHdpbnNvY2suaD4KI2VuZGlmCiNpZiBIQVZFX05FVERCX0gKI2luY2x1ZGUgPG5ldGRiLmg+CiNlbmRpZgojaWYgSEFWRV9BUlBBX0lORVRfSAojaW5jbHVkZSA8YXJwYS9pbmV0Lmg+CiNlbmRpZgoKI2luY2x1ZGUgPG5ldC1zbm1wL25ldC1zbm1wLWluY2x1ZGVzLmg+Cgp2b2lkCnVzYWdlKHZvaWQpCnsKICAgIGZwcmludGYoc3RkZXJyLCAiVXNhZ2U6IHNubXBkZiBbLUN1XSAiKTsKICAgIHNubXBfcGFyc2VfYXJnc191c2FnZShzdGRlcnIpOwogICAgZnByaW50ZihzdGRlcnIsICJcblxuIik7CiAgICBzbm1wX3BhcnNlX2FyZ3NfZGVzY3JpcHRpb25zKHN0ZGVycik7CiAgICBmcHJpbnRmKHN0ZGVyciwgIlxuc25tcGRmIG9wdGlvbnM6XG4iKTsKICAgIGZwcmludGYoc3RkZXJyLAogICAgICAgICAgICAiXHQtQ3VcdFVzZSBVQ0QtU05NUCBkc2tUYWJsZSB0byBkbyB0aGUgY2FsY3VsYXRpb25zLlxuIik7CiAgICBmcHJpbnRmKHN0ZGVyciwKICAgICAgICAgICAgIlx0XHRbTm9ybWFsbHkgdGhlIEhPU1QtUkVTT1VSQ0VTLU1JQiBpcyBjb25zdWx0ZWQgZmlyc3QuXVxuIik7Cn0KCmludCAgICAgICAgICAgICB1Y2RfbWliID0gMDsKCnN0YXRpYyB2b2lkCm9wdFByb2MoaW50IGFyZ2MsIGNoYXIgKmNvbnN0ICphcmd2LCBpbnQgb3B0KQp7CiAgICBzd2l0Y2ggKG9wdCkgewogICAgY2FzZSAnQyc6CiAgICAgICAgd2hpbGUgKCpvcHRhcmcpIHsKICAgICAgICAgICAgc3dpdGNoICgqb3B0YXJnKyspIHsKICAgICAgICAgICAgY2FzZSAndSc6CiAgICAgICAgICAgICAgICB1Y2RfbWliID0gMTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICAgICAgZnByaW50ZihzdGRlcnIsCiAgICAgICAgICAgICAgICAgICAgICAgICJVbmtub3duIGZsYWcgcGFzc2VkIHRvIC1DOiAlY1xuIiwgb3B0YXJnWy0xXSk7CiAgICAgICAgICAgICAgICBleGl0KDEpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQp9CgpzdHJ1Y3QgaHJTdG9yYWdlVGFibGUgewogICAgdV9sb25nICAgICAgICAgIGhyU3RvcmFnZUluZGV4OwogICAgb2lkICAgICAgICAgICAgKmhyU3RvcmFnZVR5cGU7CiAgICBjaGFyICAgICAgICAgICAqaHJTdG9yYWdlRGVzY3I7CiAgICB1X2xvbmcgICAgICAgICAgaHJTdG9yYWdlQWxsb2NhdGlvblVuaXRzOwogICAgdV9sb25nICAgICAgICAgIGhyU3RvcmFnZVNpemU7CiAgICB1X2xvbmcgICAgICAgICAgaHJTdG9yYWdlVXNlZDsKfTsKCmludAphZGQobmV0c25tcF9wZHUgKnBkdSwgY29uc3QgY2hhciAqbWlibm9kZW5hbWUsCiAgICBvaWQgKiBpbmRleCwgc2l6ZV90IGluZGV4bGVuKQp7CiAgICBvaWQgICAgICAgICAgICAgYmFzZVtNQVhfT0lEX0xFTl07CiAgICBzaXplX3QgICAgICAgICAgYmFzZV9sZW5ndGggPSBNQVhfT0lEX0xFTjsKCiAgICBtZW1zZXQoYmFzZSwgMCwgTUFYX09JRF9MRU4gKiBzaXplb2Yob2lkKSk7CgogICAgaWYgKCFzbm1wX3BhcnNlX29pZChtaWJub2RlbmFtZSwgYmFzZSwgJmJhc2VfbGVuZ3RoKSkgewogICAgICAgIHNubXBfcGVycm9yKG1pYm5vZGVuYW1lKTsKICAgICAgICBmcHJpbnRmKHN0ZGVyciwgImNvdWxkbid0IGZpbmQgbWliIG5vZGUgJXMsIGdpdmluZyB1cFxuIiwKICAgICAgICAgICAgICAgIG1pYm5vZGVuYW1lKTsKICAgICAgICBleGl0KDEpOwogICAgfQoKICAgIGlmIChpbmRleCAmJiBpbmRleGxlbikgewogICAgICAgIG1lbWNweSgmKGJhc2VbYmFzZV9sZW5ndGhdKSwgaW5kZXgsIGluZGV4bGVuICogc2l6ZW9mKG9pZCkpOwogICAgICAgIGJhc2VfbGVuZ3RoICs9IGluZGV4bGVuOwogICAgfQogICAgREVCVUdNU0dUTCgoImFkZCIsICJjcmVhdGVkOiAiKSk7CiAgICBERUJVR01TR09JRCgoImFkZCIsIGJhc2UsIGJhc2VfbGVuZ3RoKSk7CiAgICBERUJVR01TRygoImFkZCIsICJcbiIpKTsKICAgIHNubXBfYWRkX251bGxfdmFyKHBkdSwgYmFzZSwgYmFzZV9sZW5ndGgpOwoKICAgIHJldHVybiBiYXNlX2xlbmd0aDsKfQoKbmV0c25tcF92YXJpYWJsZV9saXN0ICoKY29sbGVjdChuZXRzbm1wX3Nlc3Npb24gKiBzcywgbmV0c25tcF9wZHUgKnBkdSwKICAgICAgICBvaWQgKiBiYXNlLCBzaXplX3QgYmFzZV9sZW5ndGgpCnsKICAgIG5ldHNubXBfcGR1ICAgICpyZXNwb25zZTsKICAgIGludCAgICAgICAgICAgICBydW5uaW5nID0gMTsKICAgIG5ldHNubXBfdmFyaWFibGVfbGlzdCAqc2F2ZWQgPSBOVUxMLCAqKnZscHAgPSAmc2F2ZWQ7CiAgICBpbnQgICAgICAgICAgICAgc3RhdHVzOwoKICAgIHdoaWxlIChydW5uaW5nKSB7CiAgICAgICAgLyoKICAgICAgICAgKiBnb3R0YSBjYXRjaCBlbSBhbGwsIGdvdHRhIGNhdGNoIGVtIGFsbCEgCiAgICAgICAgICovCiAgICAgICAgc3RhdHVzID0gc25tcF9zeW5jaF9yZXNwb25zZShzcywgcGR1LCAmcmVzcG9uc2UpOwogICAgICAgIGlmIChzdGF0dXMgIT0gU1RBVF9TVUNDRVNTIHx8ICFyZXNwb25zZSkgewogICAgICAgICAgICBzbm1wX3Nlc3NfcGVycm9yKCJzbm1wZGYiLCBzcyk7CiAgICAgICAgICAgIGV4aXQoMSk7CiAgICAgICAgfQogICAgICAgIGlmIChyZXNwb25zZS0+ZXJyc3RhdCAhPSBTTk1QX0VSUl9OT0VSUk9SKSB7CgkgICAgZnByaW50ZihzdGRlcnIsICJzbm1wZGY6IEVycm9yIGluIHBhY2tldDogJXNcbiIsCiAgICAgICAgICAgICAgICAgICAgc25tcF9lcnJzdHJpbmcocmVzcG9uc2UtPmVycnN0YXQpKTsKICAgICAgICAgICAgZXhpdCgxKTsKICAgICAgICB9CiAgICAgICAgaWYgKHNubXBfb2lkX2NvbXBhcmUocmVzcG9uc2UtPnZhcmlhYmxlcy0+bmFtZSwKCQkJICAgICBTTk1QX01JTihiYXNlX2xlbmd0aCwKCQkJCSAgICAgIHJlc3BvbnNlLT52YXJpYWJsZXMtPm5hbWVfbGVuZ3RoKSwKCQkJICAgICBiYXNlLCBiYXNlX2xlbmd0aCkgIT0gMCkKICAgICAgICAgICAgcnVubmluZyA9IDA7CiAgICAgICAgZWxzZSBpZiAocmVzcG9uc2UtPnZhcmlhYmxlcy0+dHlwZSA9PSBTTk1QX05PU1VDSElOU1RBTkNFIHx8CiAgICAgICAgICAgICAgICAgcmVzcG9uc2UtPnZhcmlhYmxlcy0+dHlwZSA9PSBTTk1QX05PU1VDSE9CSkVDVCB8fAogICAgICAgICAgICAgICAgIHJlc3BvbnNlLT52YXJpYWJsZXMtPnR5cGUgPT0gU05NUF9FTkRPRk1JQlZJRVcpCiAgICAgICAgICAgIHJ1bm5pbmcgPSAwOwogICAgICAgIGVsc2UgewogICAgICAgICAgICAvKgogICAgICAgICAgICAgKiBnZXQgcmVzcG9uc2UgCiAgICAgICAgICAgICAqLwogICAgICAgICAgICAqdmxwcCA9IHJlc3BvbnNlLT52YXJpYWJsZXM7CiAgICAgICAgICAgICgqdmxwcCktPm5leHRfdmFyaWFibGUgPSBOVUxMOyAgICAgIC8qIHNob3VsZG4ndCBiZSBhbnksIGJ1dCBqdXN0IGluIGNhc2UgKi8KCiAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAqIGNyZWF0ZSB0aGUgbmV4dCByZXF1ZXN0IAogICAgICAgICAgICAgKi8KICAgICAgICAgICAgcGR1ID0gc25tcF9wZHVfY3JlYXRlKFNOTVBfTVNHX0dFVE5FWFQpOwogICAgICAgICAgICBzbm1wX2FkZF9udWxsX3ZhcihwZHUsICgqdmxwcCktPm5hbWUsICgqdmxwcCktPm5hbWVfbGVuZ3RoKTsKCiAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAqIGZpbmlzaCBsb29wIHNldHVwIAogICAgICAgICAgICAgKi8KICAgICAgICAgICAgdmxwcCA9ICYoKCp2bHBwKS0+bmV4dF92YXJpYWJsZSk7CiAgICAgICAgICAgIHJlc3BvbnNlLT52YXJpYWJsZXMgPSBOVUxMOyAvKiBhaGgsIGZvcmdldCBhYm91dCBpdCAqLwogICAgICAgIH0KICAgICAgICBzbm1wX2ZyZWVfcGR1KHJlc3BvbnNlKTsKICAgIH0KICAgIHJldHVybiBzYXZlZDsKfQoKLyogQ29tcHV0ZXMgdmFsdWUqdW5pdHMvZGl2aXNvciBpbiBhbiBvdmVyZmxvdy1wcm9vZiB3YXkuCiAqLwp1bnNpZ25lZCBsb25nCmNvbnZlcnRfdW5pdHModW5zaWduZWQgbG9uZyB2YWx1ZSwgc2l6ZV90IHVuaXRzLCBzaXplX3QgZGl2aXNvcikKewogICAgcmV0dXJuICh1bnNpZ25lZCBsb25nKSgoZG91YmxlKXZhbHVlICogdW5pdHMgLyAoZG91YmxlKWRpdmlzb3IpOwp9CgoKaW50Cm1haW4oaW50IGFyZ2MsIGNoYXIgKmFyZ3ZbXSkKewogICAgbmV0c25tcF9zZXNzaW9uIHNlc3Npb24sICpzczsKICAgIG5ldHNubXBfcGR1ICAgICpwZHU7CiAgICBuZXRzbm1wX3BkdSAgICAqcmVzcG9uc2U7CiAgICBpbnQgICAgICAgICAgICAgYXJnOwogICAgb2lkICAgICAgICAgICAgIGJhc2VbTUFYX09JRF9MRU5dOwogICAgc2l6ZV90ICAgICAgICAgIGJhc2VfbGVuZ3RoOwogICAgaW50ICAgICAgICAgICAgIHN0YXR1czsKICAgIG5ldHNubXBfdmFyaWFibGVfbGlzdCAqc2F2ZWQgPSBOVUxMLCAqdmxwID0gc2F2ZWQsICp2bHAyOwogICAgaW50ICAgICAgICAgICAgIGNvdW50ID0gMDsKCiAgICAvKgogICAgICogZ2V0IHRoZSBjb21tb24gY29tbWFuZCBsaW5lIGFyZ3VtZW50cyAKICAgICAqLwogICAgc3dpdGNoIChhcmcgPSBzbm1wX3BhcnNlX2FyZ3MoYXJnYywgYXJndiwgJnNlc3Npb24sICJDOiIsIG9wdFByb2MpKSB7CiAgICBjYXNlIC0yOgogICAgICAgIGV4aXQoMCk7CiAgICBjYXNlIC0xOgogICAgICAgIHVzYWdlKCk7CiAgICAgICAgZXhpdCgxKTsKICAgIGRlZmF1bHQ6CiAgICAgICAgYnJlYWs7CiAgICB9CgogICAgaWYgKGFyZyAhPSBhcmdjKSB7CglmcHJpbnRmKHN0ZGVyciwgInNubXBkZjogZXh0cmEgYXJndW1lbnQ6ICVzXG4iLCBhcmd2W2FyZ10pOwoJZXhpdCgxKTsKICAgIH0KCiAgICBTT0NLX1NUQVJUVVA7CgogICAgLyoKICAgICAqIE9wZW4gYW4gU05NUCBzZXNzaW9uLgogICAgICovCiAgICBzcyA9IHNubXBfb3Blbigmc2Vzc2lvbik7CiAgICBpZiAoc3MgPT0gTlVMTCkgewogICAgICAgIC8qCiAgICAgICAgICogZGlhZ25vc2Ugc25tcF9vcGVuIGVycm9ycyB3aXRoIHRoZSBpbnB1dCBuZXRzbm1wX3Nlc3Npb24gcG9pbnRlciAKICAgICAgICAgKi8KICAgICAgICBzbm1wX3Nlc3NfcGVycm9yKCJzbm1wZGYiLCAmc2Vzc2lvbik7CiAgICAgICAgU09DS19DTEVBTlVQOwogICAgICAgIGV4aXQoMSk7CiAgICB9CgogICAgcHJpbnRmKCIlLTE4cyAlMTVzICUxNXMgJTE1cyAlNXNcbiIsICJEZXNjcmlwdGlvbiIsICJzaXplIChrQikiLAogICAgICAgICAgICJVc2VkIiwgIkF2YWlsYWJsZSIsICJVc2VkJSIpOwogICAgaWYgKHVjZF9taWIgPT0gMCkgewogICAgICAgIC8qCiAgICAgICAgICogKiBCZWdpbiBieSBmaW5kaW5nIGFsbCB0aGUgc3RvcmFnZSBwaWVjZXMgdGhhdCBhcmUgb2YKICAgICAgICAgKiAqIHR5cGUgaHJTdG9yYWdlRml4ZWREaXNrLCB3aGljaCBpcyBhIHN0YW5kYXJkIGRpc2suCiAgICAgICAgICovCiAgICAgICAgcGR1ID0gc25tcF9wZHVfY3JlYXRlKFNOTVBfTVNHX0dFVE5FWFQpOwogICAgICAgIGJhc2VfbGVuZ3RoID0KICAgICAgICAgICAgYWRkKHBkdSwgIkhPU1QtUkVTT1VSQ0VTLU1JQjpoclN0b3JhZ2VJbmRleCIsIE5VTEwsIDApOwogICAgICAgIG1lbWNweShiYXNlLCBwZHUtPnZhcmlhYmxlcy0+bmFtZSwgYmFzZV9sZW5ndGggKiBzaXplb2Yob2lkKSk7CgogICAgICAgIHZscCA9IGNvbGxlY3Qoc3MsIHBkdSwgYmFzZSwgYmFzZV9sZW5ndGgpOwoKICAgICAgICB3aGlsZSAodmxwKSB7CiAgICAgICAgICAgIHNpemVfdCAgICAgICAgICB1bml0czsKICAgICAgICAgICAgdW5zaWduZWQgbG9uZyAgIGhzc2l6ZSwgaHN1c2VkOwogICAgICAgICAgICBjaGFyICAgICAgICAgICAgZGVzY3JbU1BSSU5UX01BWF9MRU5dOwogICAgICAgICAgICBpbnQgICAgICAgICAgICAgbGVuOwoKICAgICAgICAgICAgcGR1ID0gc25tcF9wZHVfY3JlYXRlKFNOTVBfTVNHX0dFVCk7CgogICAgICAgICAgICBhZGQocGR1LCAiSE9TVC1SRVNPVVJDRVMtTUlCOmhyU3RvcmFnZURlc2NyIiwKICAgICAgICAgICAgICAgICYodmxwLT5uYW1lW2Jhc2VfbGVuZ3RoXSksIHZscC0+bmFtZV9sZW5ndGggLSBiYXNlX2xlbmd0aCk7CiAgICAgICAgICAgIGFkZChwZHUsICJIT1NULVJFU09VUkNFUy1NSUI6aHJTdG9yYWdlQWxsb2NhdGlvblVuaXRzIiwKICAgICAgICAgICAgICAgICYodmxwLT5uYW1lW2Jhc2VfbGVuZ3RoXSksIHZscC0+bmFtZV9sZW5ndGggLSBiYXNlX2xlbmd0aCk7CiAgICAgICAgICAgIGFkZChwZHUsICJIT1NULVJFU09VUkNFUy1NSUI6aHJTdG9yYWdlU2l6ZSIsCiAgICAgICAgICAgICAgICAmKHZscC0+bmFtZVtiYXNlX2xlbmd0aF0pLCB2bHAtPm5hbWVfbGVuZ3RoIC0gYmFzZV9sZW5ndGgpOwogICAgICAgICAgICBhZGQocGR1LCAiSE9TVC1SRVNPVVJDRVMtTUlCOmhyU3RvcmFnZVVzZWQiLAogICAgICAgICAgICAgICAgJih2bHAtPm5hbWVbYmFzZV9sZW5ndGhdKSwgdmxwLT5uYW1lX2xlbmd0aCAtIGJhc2VfbGVuZ3RoKTsKCiAgICAgICAgICAgIHN0YXR1cyA9IHNubXBfc3luY2hfcmVzcG9uc2Uoc3MsIHBkdSwgJnJlc3BvbnNlKTsKICAgICAgICAgICAgaWYgKHN0YXR1cyAhPSBTVEFUX1NVQ0NFU1MgfHwgIXJlc3BvbnNlKSB7CiAgICAgICAgICAgICAgICBzbm1wX3Nlc3NfcGVycm9yKCJzbm1wZGYiLCBzcyk7CiAgICAgICAgICAgICAgICBleGl0KDEpOwogICAgICAgICAgICB9CgogICAgICAgICAgICB2bHAyID0gcmVzcG9uc2UtPnZhcmlhYmxlczsKICAgICAgICAgICAgaWYgKHZscDItPnR5cGUgPT0gU05NUF9OT1NVQ0hJTlNUQU5DRSkgZ290byBuZXh0OwogICAgICAgICAgICBsZW4gPSB2bHAyLT52YWxfbGVuOwogICAgICAgICAgICBpZiAobGVuID49IFNQUklOVF9NQVhfTEVOKSBsZW4gPSBTUFJJTlRfTUFYX0xFTi0xOwogICAgICAgICAgICBtZW1jcHkoZGVzY3IsIHZscDItPnZhbC5zdHJpbmcsIGxlbik7CiAgICAgICAgICAgIGRlc2NyW2xlbl0gPSAnXDAnOwoKICAgICAgICAgICAgdmxwMiA9IHZscDItPm5leHRfdmFyaWFibGU7CiAgICAgICAgICAgIGlmICh2bHAyLT50eXBlID09IFNOTVBfTk9TVUNISU5TVEFOQ0UpIGdvdG8gbmV4dDsKICAgICAgICAgICAgdW5pdHMgPSB2bHAyLT52YWwuaW50ZWdlciA/ICoodmxwMi0+dmFsLmludGVnZXIpIDogMDsKCiAgICAgICAgICAgIHZscDIgPSB2bHAyLT5uZXh0X3ZhcmlhYmxlOwogICAgICAgICAgICBpZiAodmxwMi0+dHlwZSA9PSBTTk1QX05PU1VDSElOU1RBTkNFKSBnb3RvIG5leHQ7CiAgICAgICAgICAgIGhzc2l6ZSA9IHZscDItPnZhbC5pbnRlZ2VyID8gKih2bHAyLT52YWwuaW50ZWdlcikgOiAwOwoKICAgICAgICAgICAgdmxwMiA9IHZscDItPm5leHRfdmFyaWFibGU7CiAgICAgICAgICAgIGlmICh2bHAyLT50eXBlID09IFNOTVBfTk9TVUNISU5TVEFOQ0UpIGdvdG8gbmV4dDsKICAgICAgICAgICAgaHN1c2VkID0gdmxwMi0+dmFsLmludGVnZXIgPyAqKHZscDItPnZhbC5pbnRlZ2VyKSA6IDA7CgogICAgICAgICAgICBwcmludGYoIiUtMThzICUxNWx1ICUxNWx1ICUxNWx1ICU0bHUlJVxuIiwgZGVzY3IsCiAgICAgICAgICAgICAgICAgICB1bml0cyA/IGNvbnZlcnRfdW5pdHMoaHNzaXplLCB1bml0cywgMTAyNCkgOiBoc3NpemUsCiAgICAgICAgICAgICAgICAgICB1bml0cyA/IGNvbnZlcnRfdW5pdHMoaHN1c2VkLCB1bml0cywgMTAyNCkgOiBoc3VzZWQsCiAgICAgICAgICAgICAgICAgICB1bml0cyA/IGNvbnZlcnRfdW5pdHMoaHNzaXplLWhzdXNlZCwgdW5pdHMsIDEwMjQpIDogaHNzaXplIC0KICAgICAgICAgICAgICAgICAgIGhzdXNlZCwgaHNzaXplID8gY29udmVydF91bml0cyhoc3VzZWQsIDEwMCwgaHNzaXplKSA6CiAgICAgICAgICAgICAgICAgICBoc3VzZWQpOwoKICAgICAgICBuZXh0OgogICAgICAgICAgICB2bHAgPSB2bHAtPm5leHRfdmFyaWFibGU7CiAgICAgICAgICAgIHNubXBfZnJlZV9wZHUocmVzcG9uc2UpOwogICAgICAgICAgICBjb3VudCsrOwogICAgICAgIH0KICAgIH0KCiAgICBpZiAoY291bnQgPT0gMCkgewogICAgICAgIHNpemVfdCAgICAgICAgICB1bml0cyA9IDA7CiAgICAgICAgLyoKICAgICAgICAgKiB0aGUgaG9zdCByZXNvdXJjZXMgbWliIG11c3Qgbm90IGJlIHN1cHBvcnRlZC4gIExldHMgdHJ5IHRoZQogICAgICAgICAqIFVDRC1TTk1QLU1JQiBhbmQgaXRzIGRza1RhYmxlIAogICAgICAgICAqLwoKICAgICAgICBwZHUgPSBzbm1wX3BkdV9jcmVhdGUoU05NUF9NU0dfR0VUTkVYVCk7CiAgICAgICAgYmFzZV9sZW5ndGggPSBhZGQocGR1LCAiVUNELVNOTVAtTUlCOmRza0luZGV4IiwgTlVMTCwgMCk7CiAgICAgICAgbWVtY3B5KGJhc2UsIHBkdS0+dmFyaWFibGVzLT5uYW1lLCBiYXNlX2xlbmd0aCAqIHNpemVvZihvaWQpKTsKCiAgICAgICAgdmxwID0gY29sbGVjdChzcywgcGR1LCBiYXNlLCBiYXNlX2xlbmd0aCk7CgogICAgICAgIHdoaWxlICh2bHApIHsKICAgICAgICAgICAgdW5zaWduZWQgbG9uZyAgIGhzc2l6ZSwgaHN1c2VkOwogICAgICAgICAgICBjaGFyICAgICAgICAgICAgZGVzY3JbU1BSSU5UX01BWF9MRU5dOwogICAgICAgICAgICBpbnQgICAgICAgICAgICAgbGVuOwoKICAgICAgICAgICAgcGR1ID0gc25tcF9wZHVfY3JlYXRlKFNOTVBfTVNHX0dFVCk7CgogICAgICAgICAgICBhZGQocGR1LCAiVUNELVNOTVAtTUlCOmRza1BhdGgiLAogICAgICAgICAgICAgICAgJih2bHAtPm5hbWVbYmFzZV9sZW5ndGhdKSwgdmxwLT5uYW1lX2xlbmd0aCAtIGJhc2VfbGVuZ3RoKTsKICAgICAgICAgICAgYWRkKHBkdSwgIlVDRC1TTk1QLU1JQjpkc2tUb3RhbCIsCiAgICAgICAgICAgICAgICAmKHZscC0+bmFtZVtiYXNlX2xlbmd0aF0pLCB2bHAtPm5hbWVfbGVuZ3RoIC0gYmFzZV9sZW5ndGgpOwogICAgICAgICAgICBhZGQocGR1LCAiVUNELVNOTVAtTUlCOmRza1VzZWQiLAogICAgICAgICAgICAgICAgJih2bHAtPm5hbWVbYmFzZV9sZW5ndGhdKSwgdmxwLT5uYW1lX2xlbmd0aCAtIGJhc2VfbGVuZ3RoKTsKCiAgICAgICAgICAgIHN0YXR1cyA9IHNubXBfc3luY2hfcmVzcG9uc2Uoc3MsIHBkdSwgJnJlc3BvbnNlKTsKICAgICAgICAgICAgaWYgKHN0YXR1cyAhPSBTVEFUX1NVQ0NFU1MgfHwgIXJlc3BvbnNlKSB7CiAgICAgICAgICAgICAgICBzbm1wX3Nlc3NfcGVycm9yKCJzbm1wZGYiLCBzcyk7CiAgICAgICAgICAgICAgICBleGl0KDEpOwogICAgICAgICAgICB9CgogICAgICAgICAgICB2bHAyID0gcmVzcG9uc2UtPnZhcmlhYmxlczsKICAgICAgICAgICAgaWYgKHZscDItPnR5cGUgPT0gU05NUF9OT1NVQ0hJTlNUQU5DRSkgZ290byBuZXh0MjsKICAgICAgICAgICAgbGVuID0gdmxwMi0+dmFsX2xlbjsKICAgICAgICAgICAgaWYgKGxlbiA+PSBTUFJJTlRfTUFYX0xFTikgbGVuID0gU1BSSU5UX01BWF9MRU4tMTsKICAgICAgICAgICAgbWVtY3B5KGRlc2NyLCB2bHAyLT52YWwuc3RyaW5nLCBsZW4pOwogICAgICAgICAgICBkZXNjcltsZW5dID0gJ1wwJzsKCiAgICAgICAgICAgIHZscDIgPSB2bHAyLT5uZXh0X3ZhcmlhYmxlOwogICAgICAgICAgICBpZiAodmxwMi0+dHlwZSA9PSBTTk1QX05PU1VDSElOU1RBTkNFKSBnb3RvIG5leHQyOwogICAgICAgICAgICBoc3NpemUgPSAqKHZscDItPnZhbC5pbnRlZ2VyKTsKCiAgICAgICAgICAgIHZscDIgPSB2bHAyLT5uZXh0X3ZhcmlhYmxlOwogICAgICAgICAgICBpZiAodmxwMi0+dHlwZSA9PSBTTk1QX05PU1VDSElOU1RBTkNFKSBnb3RvIG5leHQyOwogICAgICAgICAgICBoc3VzZWQgPSAqKHZscDItPnZhbC5pbnRlZ2VyKTsKCiAgICAgICAgICAgIHByaW50ZigiJS0xOHMgJTE1bHUgJTE1bHUgJTE1bHUgJTRsdSUlXG4iLCBkZXNjciwKICAgICAgICAgICAgICAgICAgIHVuaXRzID8gY29udmVydF91bml0cyhoc3NpemUsIHVuaXRzLCAxMDI0KSA6IGhzc2l6ZSwKICAgICAgICAgICAgICAgICAgIHVuaXRzID8gY29udmVydF91bml0cyhoc3VzZWQsIHVuaXRzLCAxMDI0KSA6IGhzdXNlZCwKICAgICAgICAgICAgICAgICAgIHVuaXRzID8gY29udmVydF91bml0cyhoc3NpemUtaHN1c2VkLCB1bml0cywgMTAyNCkgOiBoc3NpemUgLQogICAgICAgICAgICAgICAgICAgaHN1c2VkLCBoc3NpemUgPyBjb252ZXJ0X3VuaXRzKGhzdXNlZCwgMTAwLCBoc3NpemUpIDoKICAgICAgICAgICAgICAgICAgIGhzdXNlZCk7CgogICAgICAgIG5leHQyOgogICAgICAgICAgICB2bHAgPSB2bHAtPm5leHRfdmFyaWFibGU7CiAgICAgICAgICAgIHNubXBfZnJlZV9wZHUocmVzcG9uc2UpOwogICAgICAgICAgICBjb3VudCsrOwogICAgICAgIH0KICAgIH0KCiAgICBpZiAoY291bnQgPT0gMCkgewogICAgICAgIGZwcmludGYoc3RkZXJyLCAiRmFpbGVkIHRvIGxvY2F0ZSBhbnkgcGFydGl0aW9ucy5cbiIpOwogICAgICAgIGV4aXQoMSk7CiAgICB9CgogICAgc25tcF9jbG9zZShzcyk7CiAgICBTT0NLX0NMRUFOVVA7CiAgICByZXR1cm4gMDsKCn0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogZW5kIG1haW4oKSAqLwo=