LyoKICogCVJlZ2lzdHJ5IEZ1bmN0aW9ucwogKgogKiBDb3B5cmlnaHQgMTk5NiBNYXJjdXMgTWVpc3NuZXIKICogQ29weXJpZ2h0IDE5OTggTWF0dGhldyBCZWNrZXIKICogQ29weXJpZ2h0IDE5OTkgU3lsdmFpbiBTdC1HZXJtYWluCiAqCiAqIERlY2VtYmVyIDIxLCAxOTk3IC0gS2V2aW4gQ296ZW5zCiAqIEZpeGVkIGJ1Z3MgaW4gdGhlIF93OTVfbG9hZHJlZygpIGZ1bmN0aW9uLiBBZGRlZCBleHRyYSBpbmZvcm1hdGlvbgogKiByZWdhcmRpbmcgdGhlIGZvcm1hdCBvZiB0aGUgV2luZG93cyAnOTUgcmVnaXN0cnkgZmlsZXMuCiAqCiAqIFRoaXMgbGlicmFyeSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IKICogbW9kaWZ5IGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYwogKiBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXIKICogdmVyc2lvbiAyLjEgb2YgdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uCiAqCiAqIFRoaXMgbGlicmFyeSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLAogKiBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZgogKiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVQogKiBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljCiAqIExpY2Vuc2UgYWxvbmcgd2l0aCB0aGlzIGxpYnJhcnk7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUKICogRm91bmRhdGlvbiwgSW5jLiwgNTkgVGVtcGxlIFBsYWNlLCBTdWl0ZSAzMzAsIEJvc3RvbiwgTUEgIDAyMTExLTEzMDcgIFVTQQogKgogKiBOT1RFUwogKiAgICBXaGVuIGNoYW5naW5nIHRoaXMgZmlsZSwgcGxlYXNlIHJlLXJ1biB0aGUgcmVndGVzdCBwcm9ncmFtIHRvIGVuc3VyZQogKiAgICB0aGUgY29uZGl0aW9ucyBhcmUgaGFuZGxlZCBwcm9wZXJseS4KICoKICogVE9ETwogKiAgICBTZWN1cml0eSBhY2Nlc3MKICogICAgT3B0aW9uIGhhbmRsaW5nCiAqICAgIFRpbWUgZm9yIFJlZ0VudW1LZXkqLCBSZWdRdWVyeUluZm9LZXkqCiAqLwoKI2luY2x1ZGUgImNvbmZpZy5oIgojaW5jbHVkZSAid2luZS9wb3J0LmgiCgojaW5jbHVkZSA8c3RkbGliLmg+CiNpbmNsdWRlIDxzdHJpbmcuaD4KI2luY2x1ZGUgPHN0ZGlvLmg+CiNpZmRlZiBIQVZFX1VOSVNURF9ICiMgaW5jbHVkZSA8dW5pc3RkLmg+CiNlbmRpZgojaW5jbHVkZSA8ZXJybm8uaD4KI2luY2x1ZGUgPHN5cy90eXBlcy5oPgojaW5jbHVkZSA8c3lzL3N0YXQuaD4KI2luY2x1ZGUgPGZjbnRsLmg+CiNpZmRlZiBIQVZFX1NZU19NTUFOX0gKIyBpbmNsdWRlIDxzeXMvbW1hbi5oPgojZW5kaWYKCiNpbmNsdWRlICJ3aW5kZWYuaCIKI2luY2x1ZGUgIndpbmVycm9yLmgiCiNpbmNsdWRlICJ3aW5yZWcuaCIKCiNpbmNsdWRlICJ3aW5lL3dpbmJhc2UxNi5oIgojaW5jbHVkZSAid2luZS9saWJyYXJ5LmgiCiNpbmNsdWRlICJ3aW5lL3NlcnZlci5oIgojaW5jbHVkZSAid2luZS91bmljb2RlLmgiCiNpbmNsdWRlICJmaWxlLmgiCgojaW5jbHVkZSAid2luZS9kZWJ1Zy5oIgoKV0lORV9ERUZBVUxUX0RFQlVHX0NIQU5ORUwocmVnKTsKCiNkZWZpbmUgU0FWRV9HTE9CQUxfUkVHQlJBTkNIX1VTRVJfREVGQVVMVCAgIi93aW5lLnVzZXJyZWciCiNkZWZpbmUgU0FWRV9HTE9CQUxfUkVHQlJBTkNIX0xPQ0FMX01BQ0hJTkUgIi93aW5lLnN5c3RlbXJlZyIKCi8qIHJlbGF0aXZlIGluIH51c2VyLy53aW5lLyA6ICovCiNkZWZpbmUgU0FWRV9MT0NBTF9SRUdCUkFOQ0hfQ1VSUkVOVF9VU0VSICAidXNlci5yZWciCiNkZWZpbmUgU0FWRV9MT0NBTF9SRUdCUkFOQ0hfVVNFUl9ERUZBVUxUICAidXNlcmRlZi5yZWciCiNkZWZpbmUgU0FWRV9MT0NBTF9SRUdCUkFOQ0hfTE9DQUxfTUFDSElORSAic3lzdGVtLnJlZyIKCnN0YXRpYyBjb25zdCBXQ0hBUiBDbGFzc2VzUm9vdFdbXSA9IHsnTScsJ2EnLCdjJywnaCcsJ2knLCduJywnZScsJ1xcJywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdTJywnbycsJ2YnLCd0JywndycsJ2EnLCdyJywnZScsJ1xcJywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdDJywnbCcsJ2EnLCdzJywncycsJ2UnLCdzJywwfTsKCiNkZWZpbmUgSVNfT1BUSU9OX0ZBTFNFKGNoKSBcCiAgICAoKGNoKSA9PSAnbicgfHwgKGNoKSA9PSAnTicgfHwgKGNoKSA9PSAnZicgfHwgKGNoKSA9PSAnRicgfHwgKGNoKSA9PSAnMCcpCgovKiBfeG1hbGxvYyBbSW50ZXJuYWxdICovCnN0YXRpYyB2b2lkICpfeG1hbGxvYyggc2l6ZV90IHNpemUgKQp7CiAgICB2b2lkICpyZXM7CgogICAgcmVzID0gbWFsbG9jIChzaXplID8gc2l6ZSA6IDEpOwogICAgaWYgKHJlcyA9PSBOVUxMKSB7CiAgICAgICAgV0FSTigiVmlydHVhbCBtZW1vcnkgZXhoYXVzdGVkLlxuIik7CiAgICAgICAgZXhpdCAoMSk7CiAgICB9CiAgICByZXR1cm4gcmVzOwp9CgovKiBfc3RyZHVwbkEgW0ludGVybmFsXSAqLwpzdGF0aWMgTFBTVFIgX3N0cmR1cG5BKExQQ1NUUiBzdHIsc2l6ZV90IGxlbikKewogICAgTFBTVFIgcmV0OwoKICAgIGlmICghc3RyKSByZXR1cm4gTlVMTDsKICAgIHJldCA9IF94bWFsbG9jKCBsZW4gKyAxICk7CiAgICBtZW1jcHkoIHJldCwgc3RyLCBsZW4gKTsKICAgIHJldFtsZW5dID0gMHgwMDsKICAgIHJldHVybiByZXQ7Cn0KCi8qIGNvbnZlcnQgYW5zaSBzdHJpbmcgdG8gdW5pY29kZSBbSW50ZXJuYWxdICovCnN0YXRpYyBMUFdTVFIgX3N0cmR1cG5BdG9XKExQQ1NUUiBzdHJBLHNpemVfdCBsZW5BKQp7CiAgICBMUFdTVFIgcmV0OwogICAgc2l6ZV90IGxlblc7CgogICAgaWYgKCFzdHJBKSByZXR1cm4gTlVMTDsKICAgIGxlblcgPSBNdWx0aUJ5dGVUb1dpZGVDaGFyKENQX0FDUCwwLHN0ckEsbGVuQSxOVUxMLDApOwogICAgcmV0ID0gX3htYWxsb2MobGVuVypzaXplb2YoV0NIQVIpK3NpemVvZihXQ0hBUikpOwogICAgTXVsdGlCeXRlVG9XaWRlQ2hhcihDUF9BQ1AsMCxzdHJBLGxlbkEscmV0LGxlblcpOwogICAgcmV0W2xlblddID0gMDsKICAgIHJldHVybiByZXQ7Cn0KCi8qIGR1bXAgYSBVbmljb2RlIHN0cmluZyB3aXRoIHByb3BlciBlc2NhcGluZyBbSW50ZXJuYWxdICovCi8qIEZJWE1FOiB0aGlzIGNvZGUgZHVwbGljYXRlcyBzZXJ2ZXIvdW5pY29kZS5jICovCnN0YXRpYyBpbnQgX2R1bXBfc3RyVyhjb25zdCBXQ0hBUiAqc3RyLHNpemVfdCBsZW4sRklMRSAqZixjaGFyIGVzY2FwZVsyXSkKewogICAgc3RhdGljIGNvbnN0IGNoYXIgZXNjYXBlc1szMl0gPSAiLi4uLi4uLmFidG52ZnIuLi4uLi4uLi4uLi4uZS4uLi4iOwogICAgY2hhciBidWZmZXJbMjU2XTsKICAgIExQU1RSIHBvcyA9IGJ1ZmZlcjsKICAgIGludCBjb3VudCA9IDA7CgogICAgZm9yICg7IGxlbjsgc3RyKyssIGxlbi0tKQogICAgewogICAgICAgIGlmIChwb3MgPiBidWZmZXIgKyBzaXplb2YoYnVmZmVyKSAtIDgpCiAgICAgICAgewogICAgICAgICAgICBmd3JpdGUoIGJ1ZmZlciwgcG9zIC0gYnVmZmVyLCAxLCBmICk7CiAgICAgICAgICAgIGNvdW50ICs9IHBvcyAtIGJ1ZmZlcjsKICAgICAgICAgICAgcG9zID0gYnVmZmVyOwogICAgICAgIH0KICAgICAgICBpZiAoKnN0ciA+IDEyNykgIC8qIGhleCBlc2NhcGUgKi8KICAgICAgICB7CiAgICAgICAgICAgIGlmIChsZW4gPiAxICYmIHN0clsxXSA8IDEyOCAmJiBpc3hkaWdpdCgoY2hhcilzdHJbMV0pKQogICAgICAgICAgICAgICAgcG9zICs9IHNwcmludGYoIHBvcywgIlxceCUwNHgiLCAqc3RyICk7CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgIHBvcyArPSBzcHJpbnRmKCBwb3MsICJcXHgleCIsICpzdHIgKTsKICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgfQogICAgICAgIGlmICgqc3RyIDwgMzIpICAvKiBvY3RhbCBvciBDIGVzY2FwZSAqLwogICAgICAgIHsKICAgICAgICAgICAgaWYgKCEqc3RyICYmIGxlbiA9PSAxKSBjb250aW51ZTsgIC8qIGRvIG5vdCBvdXRwdXQgdGVybWluYXRpbmcgTlVMTCAqLwogICAgICAgICAgICBpZiAoZXNjYXBlc1sqc3RyXSAhPSAnLicpCiAgICAgICAgICAgICAgICBwb3MgKz0gc3ByaW50ZiggcG9zLCAiXFwlYyIsIGVzY2FwZXNbKnN0cl0gKTsKICAgICAgICAgICAgZWxzZSBpZiAobGVuID4gMSAmJiBzdHJbMV0gPj0gJzAnICYmIHN0clsxXSA8PSAnNycpCiAgICAgICAgICAgICAgICBwb3MgKz0gc3ByaW50ZiggcG9zLCAiXFwlMDNvIiwgKnN0ciApOwogICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICBwb3MgKz0gc3ByaW50ZiggcG9zLCAiXFwlbyIsICpzdHIgKTsKICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgfQogICAgICAgIGlmICgqc3RyID09ICdcXCcgfHwgKnN0ciA9PSBlc2NhcGVbMF0gfHwgKnN0ciA9PSBlc2NhcGVbMV0pICpwb3MrKyA9ICdcXCc7CiAgICAgICAgKnBvcysrID0gKnN0cjsKICAgIH0KICAgIGZ3cml0ZSggYnVmZmVyLCBwb3MgLSBidWZmZXIsIDEsIGYgKTsKICAgIGNvdW50ICs9IHBvcyAtIGJ1ZmZlcjsKICAgIHJldHVybiBjb3VudDsKfQoKLyogY29udmVydCBhbnNpIHN0cmluZyB0byB1bmljb2RlIGFuZCBkdW1wIHdpdGggcHJvcGVyIGVzY2FwaW5nIFtJbnRlcm5hbF0gKi8Kc3RhdGljIGludCBfZHVtcF9zdHJBdG9XKExQQ1NUUiBzdHJBLHNpemVfdCBsZW4sRklMRSAqZixjaGFyIGVzY2FwZVsyXSkKewogICAgV0NIQVIgKnN0clc7CiAgICBpbnQgcmV0OwoKICAgIGlmIChzdHJBID09IE5VTEwpIHJldHVybiAwOwogICAgc3RyVyA9IF9zdHJkdXBuQXRvVyhzdHJBLGxlbik7CiAgICByZXQgPSBfZHVtcF9zdHJXKHN0clcsbGVuLGYsZXNjYXBlKTsKICAgIGZyZWUoc3RyVyk7CiAgICByZXR1cm4gcmV0Owp9CgovKiBhIGtleSB2YWx1ZSAqLwovKiBGSVhNRTogdGhpcyBjb2RlIGR1cGxpY2F0ZXMgc2VydmVyL3JlZ2lzdHJ5LmMgKi8Kc3RydWN0IGtleV92YWx1ZSB7CiAgICBXQ0hBUiAgICAgICAgICAgICpuYW1lVzsgICAvKiB2YWx1ZSBuYW1lICovCiAgICBpbnQgICAgICAgICAgICAgICB0eXBlOyAgICAvKiB2YWx1ZSB0eXBlICovCiAgICBzaXplX3QgICAgICAgICAgICBsZW47ICAgICAvKiB2YWx1ZSBkYXRhIGxlbmd0aCBpbiBieXRlcyAqLwogICAgdm9pZCAgICAgICAgICAgICAqZGF0YTsgICAgLyogcG9pbnRlciB0byB2YWx1ZSBkYXRhICovCn07CgovKiBkdW1wIGEgdmFsdWUgdG8gYSB0ZXh0IGZpbGUgKi8KLyogRklYTUU6IHRoaXMgY29kZSBkdXBsaWNhdGVzIHNlcnZlci9yZWdpc3RyeS5jICovCnN0YXRpYyB2b2lkIF9kdW1wX3ZhbHVlKHN0cnVjdCBrZXlfdmFsdWUgKnZhbHVlLEZJTEUgKmYpCnsKICAgIGludCBpLCBjb3VudDsKCiAgICBpZiAodmFsdWUtPm5hbWVXWzBdKSB7CiAgICAgICAgZnB1dGMoICdcIicsIGYgKTsKICAgICAgICBjb3VudCA9IDEgKyBfZHVtcF9zdHJXKHZhbHVlLT5uYW1lVyxzdHJsZW5XKHZhbHVlLT5uYW1lVyksZiwiXCJcIiIpOwogICAgICAgIGNvdW50ICs9IGZwcmludGYoIGYsICJcIj0iICk7CiAgICB9CiAgICBlbHNlIGNvdW50ID0gZnByaW50ZiggZiwgIkA9IiApOwoKICAgIHN3aXRjaCh2YWx1ZS0+dHlwZSkgewogICAgICAgIGNhc2UgUkVHX1NaOgogICAgICAgIGNhc2UgUkVHX0VYUEFORF9TWjoKICAgICAgICBjYXNlIFJFR19NVUxUSV9TWjoKICAgICAgICAgICAgaWYgKHZhbHVlLT50eXBlICE9IFJFR19TWikgZnByaW50ZiggZiwgInN0ciglZCk6IiwgdmFsdWUtPnR5cGUgKTsKICAgICAgICAgICAgZnB1dGMoICdcIicsIGYgKTsKICAgICAgICAgICAgaWYgKHZhbHVlLT5kYXRhKSBfZHVtcF9zdHJXKHZhbHVlLT5kYXRhLHZhbHVlLT5sZW4vc2l6ZW9mKFdDSEFSKSxmLCJcIlwiIik7CiAgICAgICAgICAgIGZwdXRjKCAnXCInLCBmICk7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgUkVHX0RXT1JEOgogICAgICAgICAgICBpZiAodmFsdWUtPmxlbiA9PSBzaXplb2YoRFdPUkQpKSB7CiAgICAgICAgICAgICAgICBEV09SRCBkdzsKICAgICAgICAgICAgICAgIG1lbWNweSggJmR3LCB2YWx1ZS0+ZGF0YSwgc2l6ZW9mKERXT1JEKSApOwogICAgICAgICAgICAgICAgZnByaW50ZiggZiwgImR3b3JkOiUwOGx4IiwgZHcgKTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9CiAgICAgICAgICAgIC8qIGVsc2UgZmFsbCB0aHJvdWdoICovCiAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgaWYgKHZhbHVlLT50eXBlID09IFJFR19CSU5BUlkpIGNvdW50ICs9IGZwcmludGYoIGYsICJoZXg6IiApOwogICAgICAgICAgICBlbHNlIGNvdW50ICs9IGZwcmludGYoIGYsICJoZXgoJXgpOiIsIHZhbHVlLT50eXBlICk7CiAgICAgICAgICAgIGZvciAoaSA9IDA7IGkgPCB2YWx1ZS0+bGVuOyBpKyspIHsKICAgICAgICAgICAgICAgIGNvdW50ICs9IGZwcmludGYoIGYsICIlMDJ4IiwgKigodW5zaWduZWQgY2hhciAqKXZhbHVlLT5kYXRhICsgaSkgKTsKICAgICAgICAgICAgICAgIGlmIChpIDwgdmFsdWUtPmxlbi0xKSB7CiAgICAgICAgICAgICAgICAgICAgZnB1dGMoICcsJywgZiApOwogICAgICAgICAgICAgICAgICAgIGlmICgrK2NvdW50ID4gNzYpIHsKICAgICAgICAgICAgICAgICAgICAgICAgZnByaW50ZiggZiwgIlxcXG4gICIgKTsKICAgICAgICAgICAgICAgICAgICAgICAgY291bnQgPSAyOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICBicmVhazsKICAgIH0KICAgIGZwdXRjKCAnXG4nLCBmICk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCi8qIFdJTkRPV1MgMzEgUkVHSVNUUlkgTE9BREVSLCBzdXBwbGllZCBieSBUb3IgU2r4d2FsbCwgdG9yQHNuLm5vICovCi8qCiAgICByZWdoYWNrIC0gd2luZG93cyAzLjExIHJlZ2lzdHJ5IGRhdGEgZm9ybWF0IGRlbW8gcHJvZ3JhbS4KCiAgICBUaGUgcmVnLmRhdCBmaWxlIGhhcyAzIHBhcnRzLCBhIGhlYWRlciwgYSB0YWJsZSBvZiA4LWJ5dGUgZW50cmllcyB0aGF0IGlzCiAgICBhIGNvbWJpbmVkIGhhc2ggdGFibGUgYW5kIHRyZWUgZGVzY3JpcHRpb24sIGFuZCBmaW5hbGx5IGEgdGV4dCB0YWJsZS4KCiAgICBUaGUgaGVhZGVyIGlzIG9idmlvdXMgZnJvbSB0aGUgc3RydWN0IGhlYWRlci4gVGhlIHRhYm9mZjEgYW5kIHRhYm9mZjIKICAgIGZpZWxkcyBhcmUgYWx3YXlzIDB4MjAsIGFuZCB0aGVpciB1c2FnZSBpcyB1bmtub3duLgoKICAgIFRoZSA4LWJ5dGUgZW50cnkgdGFibGUgaGFzIHZhcmlvdXMgZW50cnkgdHlwZXMuCgogICAgdGFiZW50WzBdIGlzIGEgcm9vdCBpbmRleC4gVGhlIHNlY29uZCB3b3JkIGhhcyB0aGUgaW5kZXggb2YgdGhlIHJvb3Qgb2YKICAgICAgICAgICAgdGhlIGRpcmVjdG9yeS4KICAgIHRhYmVudFsxLi5oYXNoc2l6ZV0gaXMgYSBoYXNoIHRhYmxlLiBUaGUgZmlyc3Qgd29yZCBpbiB0aGUgaGFzaCBlbnRyeSBpcwogICAgICAgICAgICB0aGUgaW5kZXggb2YgdGhlIGtleS92YWx1ZSB0aGF0IGhhcyB0aGF0IGhhc2guIERhdGEgd2l0aCB0aGUgc2FtZQogICAgICAgICAgICBoYXNoIHZhbHVlIGFyZSBvbiBhIGNpcmN1bGFyIGxpc3QuIFRoZSBvdGhlciB0aHJlZSB3b3JkcyBpbiB0aGUKICAgICAgICAgICAgaGFzaCBlbnRyeSBhcmUgYWx3YXlzIHplcm8uCiAgICB0YWJlbnRbaGFzaHNpemUuLnRhYmNudF0gaXMgdGhlIHRyZWUgc3RydWN0dXJlLiBUaGVyZSBhcmUgdHdvIGtpbmRzIG9mCiAgICAgICAgICAgIGVudHJ5OiBkaXJlbnQgYW5kIGtleWVudC92YWxlbnQuIFRoZXkgYXJlIGlkZW50aWZpZWQgYnkgY29udGV4dC4KICAgIHRhYmVudFtmcmVlaWR4XSBpcyB0aGUgZmlyc3QgZnJlZSBlbnRyeS4gVGhlIGZpcnN0IHdvcmQgaW4gYSBmcmVlIGVudHJ5CiAgICAgICAgICAgIGlzIHRoZSBpbmRleCBvZiB0aGUgbmV4dCBmcmVlIGVudHJ5LiBUaGUgbGFzdCBoYXMgMCBhcyBhIGxpbmsuCiAgICAgICAgICAgIFRoZSBvdGhlciB0aHJlZSB3b3JkcyBpbiB0aGUgZnJlZSBsaXN0IGFyZSBwcm9iYWJseSBpcnJlbGV2YW50LgoKICAgIEVudHJpZXMgaW4gdGV4dCB0YWJsZSBhcmUgcHJlY2VkZWQgYnkgYSB3b3JkIGF0IG9mZnNldC0yLiBUaGlzIHdvcmQKICAgIGhhcyB0aGUgdmFsdWUgKDIqaW5kZXgpKzEsIHdoZXJlIGluZGV4IGlzIHRoZSByZWZlcnJpbmcga2V5ZW50L3ZhbGVudAogICAgZW50cnkgaW4gdGhlIHRhYmxlLiBJIGhhdmUgbm8gc3VnZ2VzdGlvbiBmb3IgdGhlIDIqIGFuZCB0aGUgKzEuCiAgICBGb2xsb3dpbmcgdGhlIHdvcmQsIHRoZXJlIGFyZSBOIGJ5dGVzIG9mIGRhdGEsIGFzIHBlciB0aGUga2V5ZW50L3ZhbGVudAogICAgZW50cnkgbGVuZ3RoLiBUaGUgb2Zmc2V0IG9mIHRoZSBrZXllbnQvdmFsZW50IGVudHJ5IGlzIGZyb20gdGhlIHN0YXJ0CiAgICBvZiB0aGUgdGV4dCB0YWJsZSB0byB0aGUgZmlyc3QgZGF0YSBieXRlLgoKICAgIFRoaXMgaW5mb3JtYXRpb24gaXMgbm90IGF2YWlsYWJsZSBmcm9tIE1pY3Jvc29mdC4gVGhlIGRhdGEgZm9ybWF0IGlzCiAgICBkZWR1Y2VkIGZyb20gdGhlIHJlZy5kYXQgZmlsZSBieSBtZS4gTWlzdGFrZXMgbWF5CiAgICBoYXZlIGJlZW4gbWFkZS4gSSBjbGFpbSBubyByaWdodHMgYW5kIGdpdmUgbm8gZ3VhcmFudGVlcyBmb3IgdGhpcyBwcm9ncmFtLgoKICAgIFRvciBTavh3YWxsLCB0b3JAc24ubm8KKi8KCi8qIHJlZy5kYXQgaGVhZGVyIGZvcm1hdCAqLwpzdHJ1Y3QgX3czMV9oZWFkZXIgewogICAgY2hhcgkJY29va2llWzhdOwkvKiAnU0hDQzMuMTAnICovCiAgICB1bnNpZ25lZCBsb25nCXRhYm9mZjE7CS8qIG9mZnNldCBvZiBoYXNoIHRhYmxlICg/PykgPSAweDIwICovCiAgICB1bnNpZ25lZCBsb25nCXRhYm9mZjI7CS8qIG9mZnNldCBvZiBpbmRleCB0YWJsZSAoPz8pID0gMHgyMCAqLwogICAgdW5zaWduZWQgbG9uZwl0YWJjbnQ7CQkvKiBudW1iZXIgb2YgZW50cmllcyBpbiBpbmRleCB0YWJsZSAqLwogICAgdW5zaWduZWQgbG9uZwl0ZXh0b2ZmOwkvKiBvZmZzZXQgb2YgdGV4dCBwYXJ0ICovCiAgICB1bnNpZ25lZCBsb25nCXRleHRzaXplOwkvKiBieXRlIHNpemUgb2YgdGV4dCBwYXJ0ICovCiAgICB1bnNpZ25lZCBzaG9ydAloYXNoc2l6ZTsJLyogaGFzaCBzaXplICovCiAgICB1bnNpZ25lZCBzaG9ydAlmcmVlaWR4OwkvKiBmcmVlIGluZGV4ICovCn07CgovKiBnZW5lcmljIGZvcm1hdCBvZiB0YWJsZSBlbnRyaWVzICovCnN0cnVjdCBfdzMxX3RhYmVudCB7CiAgICB1bnNpZ25lZCBzaG9ydCB3MCwgdzEsIHcyLCB3MzsKfTsKCi8qIGRpcmVjdG9yeSB0YWJlbnQ6ICovCnN0cnVjdCBfdzMxX2RpcmVudCB7CiAgICB1bnNpZ25lZCBzaG9ydAlzaWJsaW5nX2lkeDsJLyogdGFibGUgaW5kZXggb2Ygc2libGluZyBkaXJlbnQgKi8KICAgIHVuc2lnbmVkIHNob3J0CWNoaWxkX2lkeDsJLyogdGFibGUgaW5kZXggb2YgY2hpbGQgZGlyZW50ICovCiAgICB1bnNpZ25lZCBzaG9ydAlrZXlfaWR4OwkvKiB0YWJsZSBpbmRleCBvZiBrZXkga2V5ZW50ICovCiAgICB1bnNpZ25lZCBzaG9ydAl2YWx1ZV9pZHg7CS8qIHRhYmxlIGluZGV4IG9mIHZhbHVlIHZhbGVudCAqLwp9OwoKLyoga2V5IHRhYmVudDogKi8Kc3RydWN0IF93MzFfa2V5ZW50IHsKICAgIHVuc2lnbmVkIHNob3J0CWhhc2hfaWR4OwkvKiBoYXNoIGNoYWluIGluZGV4IGZvciBzdHJpbmcgKi8KICAgIHVuc2lnbmVkIHNob3J0CXJlZmNudDsJCS8qIHJlZmVyZW5jZSBjb3VudCAqLwogICAgdW5zaWduZWQgc2hvcnQJbGVuZ3RoOwkJLyogbGVuZ3RoIG9mIHN0cmluZyAqLwogICAgdW5zaWduZWQgc2hvcnQJc3RyaW5nX29mZjsJLyogb2Zmc2V0IG9mIHN0cmluZyBpbiB0ZXh0IHRhYmxlICovCn07CgovKiB2YWx1ZSB0YWJlbnQ6ICovCnN0cnVjdCBfdzMxX3ZhbGVudCB7CiAgICB1bnNpZ25lZCBzaG9ydAloYXNoX2lkeDsJLyogaGFzaCBjaGFpbiBpbmRleCBmb3Igc3RyaW5nICovCiAgICB1bnNpZ25lZCBzaG9ydAlyZWZjbnQ7CQkvKiByZWZlcmVuY2UgY291bnQgKi8KICAgIHVuc2lnbmVkIHNob3J0CWxlbmd0aDsJCS8qIGxlbmd0aCBvZiBzdHJpbmcgKi8KICAgIHVuc2lnbmVkIHNob3J0CXN0cmluZ19vZmY7CS8qIG9mZnNldCBvZiBzdHJpbmcgaW4gdGV4dCB0YWJsZSAqLwp9OwoKLyogcmVjdXJzaXZlIGhlbHBlciBmdW5jdGlvbiB0byBkaXNwbGF5IGEgZGlyZWN0b3J5IHRyZWUgIFtJbnRlcm5hbF0gKi8Kdm9pZCBfdzMxX2R1bXB0cmVlKHVuc2lnbmVkIHNob3J0IGlkeCx1bnNpZ25lZCBjaGFyICp0eHQsc3RydWN0IF93MzFfdGFiZW50ICp0YWIsc3RydWN0IF93MzFfaGVhZGVyICpoZWFkLEhLRVkgaGtleSx0aW1lX3QgbGFzdG1vZGlmaWVkLCBpbnQgbGV2ZWwpCnsKICAgIHN0YXRpYyBjb25zdCBXQ0hBUiBjbGFzc2VzV1tdID0geycuJywnYycsJ2wnLCdhJywncycsJ3MnLCdlJywncycsMH07CiAgICBzdHJ1Y3QgX3czMV9kaXJlbnQgKmRpcjsKICAgIHN0cnVjdCBfdzMxX2tleWVudCAqa2V5OwogICAgc3RydWN0IF93MzFfdmFsZW50ICp2YWw7CiAgICBIS0VZIHN1YmtleSA9IDA7CiAgICBPQkpFQ1RfQVRUUklCVVRFUyBhdHRyOwogICAgVU5JQ09ERV9TVFJJTkcgbmFtZVcsIHZhbHVlVzsKICAgIHN0YXRpYyBXQ0hBUiB0YWlsWzQwMF07CgogICAgYXR0ci5MZW5ndGggPSBzaXplb2YoYXR0cik7CiAgICBhdHRyLlJvb3REaXJlY3RvcnkgPSBoa2V5OwogICAgYXR0ci5PYmplY3ROYW1lID0gJm5hbWVXOwogICAgYXR0ci5BdHRyaWJ1dGVzID0gMDsKICAgIGF0dHIuU2VjdXJpdHlEZXNjcmlwdG9yID0gTlVMTDsKICAgIGF0dHIuU2VjdXJpdHlRdWFsaXR5T2ZTZXJ2aWNlID0gTlVMTDsKICAgIFJ0bEluaXRVbmljb2RlU3RyaW5nKCAmdmFsdWVXLCBOVUxMICk7CgogICAgd2hpbGUgKGlkeCE9MCkgewogICAgICAgIGRpcj0oc3RydWN0IF93MzFfZGlyZW50KikmdGFiW2lkeF07CgogICAgICAgIGlmIChkaXItPmtleV9pZHgpIHsKICAgICAgICAgICAgRFdPUkQgbGVuOwogICAgICAgICAgICBrZXkgPSAoc3RydWN0IF93MzFfa2V5ZW50KikmdGFiW2Rpci0+a2V5X2lkeF07CgogICAgICAgICAgICBSdGxNdWx0aUJ5dGVUb1VuaWNvZGVOKCB0YWlsLCBzaXplb2YodGFpbCktc2l6ZW9mKFdDSEFSKSwgJmxlbiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJnR4dFtrZXktPnN0cmluZ19vZmZdLCBrZXktPmxlbmd0aCk7CiAgICAgICAgICAgIHRhaWxbbGVuL3NpemVvZihXQ0hBUildID0gMDsKCiAgICAgICAgICAgIC8qIGFsbCB0b3BsZXZlbCBlbnRyaWVzIEFORCB0aGUgZW50cmllcyBpbiB0aGUKICAgICAgICAgICAgICogdG9wbGV2ZWwgc3ViZGlyZWN0b3J5IGJlbG9uZyB0byBcU09GVFdBUkVcQ2xhc3NlcwogICAgICAgICAgICAgKi8KICAgICAgICAgICAgaWYgKCFsZXZlbCAmJiAhc3RyY21wVyh0YWlsLGNsYXNzZXNXKSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgX3czMV9kdW1wdHJlZShkaXItPmNoaWxkX2lkeCx0eHQsdGFiLGhlYWQsaGtleSxsYXN0bW9kaWZpZWQsbGV2ZWwrMSk7CiAgICAgICAgICAgICAgICBpZHg9ZGlyLT5zaWJsaW5nX2lkeDsKICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAoc3Via2V5KSBOdENsb3NlKCBzdWJrZXkgKTsKICAgICAgICAgICAgUnRsSW5pdFVuaWNvZGVTdHJpbmcoICZuYW1lVywgdGFpbCApOwogICAgICAgICAgICBpZiAoTnRDcmVhdGVLZXkoICZzdWJrZXksIEtFWV9BTExfQUNDRVNTLCAmYXR0ciwgMCwgTlVMTCwgMCwgTlVMTCApKSBzdWJrZXkgPSAwOwoKICAgICAgICAgICAgLyogb25seSBhZGQgaWYgbGVhZiBub2RlIG9yIHZhbHVlZCBub2RlICovCiAgICAgICAgICAgIGlmIChkaXItPnZhbHVlX2lkeCE9MHx8ZGlyLT5jaGlsZF9pZHg9PTApIHsKICAgICAgICAgICAgICAgIGlmIChkaXItPnZhbHVlX2lkeCkgewogICAgICAgICAgICAgICAgICAgIERXT1JEIGxlbjsKICAgICAgICAgICAgICAgICAgICB2YWw9KHN0cnVjdCBfdzMxX3ZhbGVudCopJnRhYltkaXItPnZhbHVlX2lkeF07CiAgICAgICAgICAgICAgICAgICAgUnRsTXVsdGlCeXRlVG9Vbmljb2RlTiggdGFpbCwgc2l6ZW9mKHRhaWwpIC0gc2l6ZW9mKFdDSEFSKSwgJmxlbiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmdHh0W3ZhbC0+c3RyaW5nX29mZl0sIHZhbC0+bGVuZ3RoKTsKICAgICAgICAgICAgICAgICAgICB0YWlsW2xlbi9zaXplb2YoV0NIQVIpXSA9IDA7CiAgICAgICAgICAgICAgICAgICAgTnRTZXRWYWx1ZUtleSggc3Via2V5LCAmdmFsdWVXLCAwLCBSRUdfU1osIHRhaWwsIGxlbiArIHNpemVvZihXQ0hBUikgKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0gZWxzZSBUUkFDRSgic3RyYW5nZTogbm8gZGlyZWN0b3J5IGtleSBuYW1lLCBpZHg9JTA0eFxuIiwgaWR4KTsKICAgICAgICBfdzMxX2R1bXB0cmVlKGRpci0+Y2hpbGRfaWR4LHR4dCx0YWIsaGVhZCxzdWJrZXksbGFzdG1vZGlmaWVkLGxldmVsKzEpOwogICAgICAgIGlkeD1kaXItPnNpYmxpbmdfaWR4OwogICAgfQogICAgaWYgKHN1YmtleSkgTnRDbG9zZSggc3Via2V5ICk7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIF93MzFfbG9hZHJlZyBbSW50ZXJuYWxdCiAqLwp2b2lkIF93MzFfbG9hZHJlZyh2b2lkKQp7CiAgICBIRklMRSBoZjsKICAgIEhLRVkgcm9vdDsKICAgIE9CSkVDVF9BVFRSSUJVVEVTIGF0dHI7CiAgICBVTklDT0RFX1NUUklORyBuYW1lVzsKICAgIHN0cnVjdCBfdzMxX2hlYWRlcgloZWFkOwogICAgc3RydWN0IF93MzFfdGFiZW50CSp0YWI7CiAgICB1bnNpZ25lZCBjaGFyCQkqdHh0OwogICAgdW5zaWduZWQgaW50CQlsZW47CiAgICBPRlNUUlVDVAkJb2ZzOwogICAgQllfSEFORExFX0ZJTEVfSU5GT1JNQVRJT04gaGZpbmZvOwogICAgdGltZV90CQkJbGFzdG1vZGlmaWVkOwoKICAgIFRSQUNFKCIodm9pZClcbiIpOwoKICAgIGhmID0gT3BlbkZpbGUoInJlZy5kYXQiLCZvZnMsT0ZfUkVBRCk7CiAgICBpZiAoaGY9PUhGSUxFX0VSUk9SKSByZXR1cm47CgogICAgLyogcmVhZCAmIGR1bXAgaGVhZGVyICovCiAgICBpZiAoc2l6ZW9mKGhlYWQpIT1fbHJlYWQoaGYsJmhlYWQsc2l6ZW9mKGhlYWQpKSkgewogICAgICAgIEVSUigicmVnLmRhdCBpcyB0b28gc2hvcnQuXG4iKTsKICAgICAgICBfbGNsb3NlKGhmKTsKICAgICAgICByZXR1cm47CiAgICB9CiAgICBpZiAobWVtY21wKGhlYWQuY29va2llLCAiU0hDQzMuMTAiLCBzaXplb2YoaGVhZC5jb29raWUpKSE9MCkgewogICAgICAgIEVSUigicmVnLmRhdCBoYXMgYmFkIHNpZ25hdHVyZS5cbiIpOwogICAgICAgIF9sY2xvc2UoaGYpOwogICAgICAgIHJldHVybjsKICAgIH0KCiAgICBsZW4gPSBoZWFkLnRhYmNudCAqIHNpemVvZihzdHJ1Y3QgX3czMV90YWJlbnQpOwogICAgLyogcmVhZCBhbmQgZHVtcCBpbmRleCB0YWJsZSAqLwogICAgdGFiID0gX3htYWxsb2MobGVuKTsKICAgIGlmIChsZW4hPV9scmVhZChoZix0YWIsbGVuKSkgewogICAgICAgIEVSUigiY291bGRuJ3QgcmVhZCAlZCBieXRlcy5cbiIsbGVuKTsKICAgICAgICBmcmVlKHRhYik7CiAgICAgICAgX2xjbG9zZShoZik7CiAgICAgICAgcmV0dXJuOwogICAgfQoKICAgIC8qIHJlYWQgdGV4dCAqLwogICAgdHh0ID0gX3htYWxsb2MoaGVhZC50ZXh0c2l6ZSk7CiAgICBpZiAoLTE9PV9sbHNlZWsoaGYsaGVhZC50ZXh0b2ZmLFNFRUtfU0VUKSkgewogICAgICAgIEVSUigiY291bGRuJ3Qgc2VlayB0byB0ZXh0YmxvY2suXG4iKTsKICAgICAgICBmcmVlKHRhYik7CiAgICAgICAgZnJlZSh0eHQpOwogICAgICAgIF9sY2xvc2UoaGYpOwogICAgICAgIHJldHVybjsKICAgIH0KICAgIGlmIChoZWFkLnRleHRzaXplIT1fbHJlYWQoaGYsdHh0LGhlYWQudGV4dHNpemUpKSB7CiAgICAgICAgRVJSKCJ0ZXh0YmxvY2sgdG9vIHNob3J0ICglZCBpbnN0ZWFkIG9mICVsZCkuXG4iLGxlbixoZWFkLnRleHRzaXplKTsKICAgICAgICBmcmVlKHRhYik7CiAgICAgICAgZnJlZSh0eHQpOwogICAgICAgIF9sY2xvc2UoaGYpOwogICAgICAgIHJldHVybjsKICAgIH0KCiAgICBpZiAoIUdldEZpbGVJbmZvcm1hdGlvbkJ5SGFuZGxlKChIQU5ETEUpaGYsJmhmaW5mbykpIHsKICAgICAgICBFUlIoIkdldEZpbGVJbmZvcm1hdGlvbkJ5SGFuZGxlIGZhaWxlZD8uXG4iKTsKICAgICAgICBmcmVlKHRhYik7CiAgICAgICAgZnJlZSh0eHQpOwogICAgICAgIF9sY2xvc2UoaGYpOwogICAgICAgIHJldHVybjsKICAgIH0KICAgIGxhc3Rtb2RpZmllZCA9IERPU0ZTX0ZpbGVUaW1lVG9Vbml4VGltZSgmaGZpbmZvLmZ0TGFzdFdyaXRlVGltZSxOVUxMKTsKCiAgICBhdHRyLkxlbmd0aCA9IHNpemVvZihhdHRyKTsKICAgIGF0dHIuUm9vdERpcmVjdG9yeSA9IDA7CiAgICBhdHRyLk9iamVjdE5hbWUgPSAmbmFtZVc7CiAgICBhdHRyLkF0dHJpYnV0ZXMgPSAwOwogICAgYXR0ci5TZWN1cml0eURlc2NyaXB0b3IgPSBOVUxMOwogICAgYXR0ci5TZWN1cml0eVF1YWxpdHlPZlNlcnZpY2UgPSBOVUxMOwogICAgUnRsSW5pdFVuaWNvZGVTdHJpbmcoICZuYW1lVywgQ2xhc3Nlc1Jvb3RXICk7CgogICAgaWYgKCFOdENyZWF0ZUtleSggJnJvb3QsIEtFWV9BTExfQUNDRVNTLCAmYXR0ciwgMCwgTlVMTCwgMCwgTlVMTCApKQogICAgewogICAgICAgIF93MzFfZHVtcHRyZWUodGFiWzBdLncxLHR4dCx0YWIsJmhlYWQscm9vdCxsYXN0bW9kaWZpZWQsMCk7CiAgICAgICAgTnRDbG9zZSggcm9vdCApOwogICAgfQogICAgZnJlZSh0YWIpOwogICAgZnJlZSh0eHQpOwogICAgX2xjbG9zZShoZik7CiAgICByZXR1cm47Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KLyogICAgICAgICAgICAgICAgICAgICAgICB3aW5kb3dzIDk1IHJlZ2lzdHJ5IGxvYWRlciAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqLwovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgovKiBTRUNUSU9OIDE6IG1haW4gaGVhZGVyCiAqCiAqIG9uY2UgYXQgb2Zmc2V0IDAKICovCiNkZWZpbmUJVzk1X1JFR19DUkVHX0lECTB4NDc0NTUyNDMKCnR5cGVkZWYgc3RydWN0IHsKICAgIERXT1JECWlkOwkJLyogIkNSRUciID0gVzk1X1JFR19DUkVHX0lEICovCiAgICBEV09SRAl2ZXJzaW9uOwkvKiA/Pz8/IDB4MDAwMTAwMDAgKi8KICAgIERXT1JECXJnZGJfb2ZmOwkvKiAweDA4IE9mZnNldCBvZiAxc3QgUkdEQi1ibG9jayAqLwogICAgRFdPUkQJdWsyOwkJLyogMHgwYyAqLwogICAgV09SRAlyZ2RiX251bTsJLyogMHgxMCAjIG9mIFJHREItYmxvY2tzICovCiAgICBXT1JECXVrMzsKICAgIERXT1JECXVrWzNdOwogICAgLyogcmdrbiAqLwp9IF93OTVjcmVnOwoKLyogU0VDVElPTiAyOiBEaXJlY3RvcnkgaW5mb3JtYXRpb24gKHRyZWUgc3RydWN0dXJlKQogKgogKiBvbmNlIG9uIG9mZnNldCAweDIwCiAqCiAqIHN0cnVjdHVyZTogW3Jna25dW2RrZV0qCShyZXBlYXQgdGlsbCBsYXN0X2RrZSBpcyByZWFjaGVkKQogKi8KI2RlZmluZQlXOTVfUkVHX1JHS05fSUQJMHg0ZTRiNDc1MgoKdHlwZWRlZiBzdHJ1Y3QgewogICAgRFdPUkQJaWQ7CQkvKiJSR0tOIiA9IFc5NV9SRUdfUkdLTl9JRCAqLwogICAgRFdPUkQJc2l6ZTsJCS8qIFNpemUgb2YgdGhlIFJHS04tYmxvY2sgKi8KICAgIERXT1JECXJvb3Rfb2ZmOwkvKiBSZWwuIE9mZnNldCBvZiB0aGUgcm9vdC1yZWNvcmQgKi8KICAgIERXT1JEICAgbGFzdF9ka2U7ICAgICAgIC8qIE9mZnNldCB0byBsYXN0IERLRSA/ICovCiAgICBEV09SRAl1a1s0XTsKfSBfdzk1cmdrbjsKCi8qIERpc2sgS2V5IEVudHJ5IFN0cnVjdHVyZQogKgogKiB0aGUgMXN0IGVudHJ5IGluIGEgInVzdWFsIiByZWdpc3RyeSBmaWxlIGlzIGEgbnVsLWVudHJ5IHdpdGggc3Via2V5czogdGhlCiAqIGhpdmUgaXRzZWxmLiBJdCBsb29rcyB0aGUgc2FtZSBsaWtlIG90aGVyIGtleXMuIEV2ZW4gdGhlIElELW51bWJlciBjYW4KICogYmUgYW55IHZhbHVlLgogKgogKiBUaGUgImhhc2giLXZhbHVlIGlzIGEgdmFsdWUgcmVwcmVzZW50aW5nIHRoZSBrZXkncyBuYW1lLiBXaW5kb3dzIHdpbGwgbm90CiAqIHNlYXJjaCBmb3IgdGhlIG5hbWUsIGJ1dCBmb3IgYSBtYXRjaGluZyBoYXNoLXZhbHVlLiBpZiBpdCBmaW5kcyBvbmUsIGl0CiAqIHdpbGwgY29tcGFyZSB0aGUgYWN0dWFsIHN0cmluZyBpbmZvLCBvdGhlcndpc2UgY29udGludWUgd2l0aCB0aGUgbmV4dCBrZXkuCiAqIFRvIGNhbGN1bGF0ZSB0aGUgaGFzaCBpbml0aWFsaXplIGEgRC1Xb3JkIHdpdGggMCBhbmQgYWRkIGFsbCBBU0NJSS12YWx1ZXMKICogb2YgdGhlIHN0cmluZyB3aGljaCBhcmUgc21hbGxlciB0aGFuIDB4ODAgKDEyOCkgdG8gdGhpcyBELVdvcmQuCiAqCiAqIElmIHlvdSB3YW50IHRvIG1vZGlmeSBrZXkgbmFtZXMsIGFsc28gbW9kaWZ5IHRoZSBoYXNoLXZhbHVlcywgc2luY2UgdGhleQogKiBjYW5ub3QgYmUgZm91bmQgYWdhaW4gKGFsdGhvdWdoIHRoZXkgd291bGQgYmUgZGlzcGxheWVkIGluIFJFR0VESVQpCiAqIEVuZCBvZiBsaXN0LXBvaW50ZXJzIGFyZSBmaWxsZWQgd2l0aCAweEZGRkZGRkZGCiAqCiAqIERpc2sga2V5cyBhcmUgbGF5ZWQgb3V0IGZsYXQgLi4uIEJ1dCwgc29tZXRpbWVzLCBuckxTIGFuZCBuck1TIGFyZSBib3RoCiAqIDB4RkZGRiwgd2hpY2ggbWVhbnMgc2tpcHBpbmcgb3ZlciBuZXh0a2V5b2Zmc2V0IGJ5dGVzIChpbmNsdWRpbmcgdGhpcwogKiBzdHJ1Y3R1cmUpIGFuZCByZWFkaW5nIGFub3RoZXIgUkdEQl9zZWN0aW9uLgogKgogKiBUaGUgbGFzdCBES0UgKHNlZSBmaWVsZCBsYXN0X2RrZSBpbiBfdzk1X3Jna24pIGhhcyBvbmx5IDMgRFdPUkRzIHdpdGgKICogMHg4MDAwMDAwMCAoRU9MIGluZGljYXRvciA/KSBhcyB4MSwgdGhlIGhhc2ggdmFsdWUgYW5kIDB4RkZGRkZGRkYgYXMgeDMuCiAqIFRoZSByZW1haW5pbmcgc3BhY2UgYmV0d2VlbiBsYXN0X2RrZSBhbmQgdGhlIG9mZnNldCBjYWxjdWxhdGVkIGZyb20KICogcmdrbi0+c2l6ZSBzZWVtcyB0byBiZSBmcmVlIGZvciB1c2UgZm9yIG1vcmUgZGtlOnMuCiAqIFNvIGl0IHNlZW1zIGlmIG1vcmUgZGtlOnMgYXJlIGFkZGVkLCB0aGV5IGFyZSBhZGRlZCB0byB0aGF0IHNwYWNlIGFuZAogKiBsYXN0X2RrZSBpcyBncm93biwgYW5kIGluIGNhc2UgdGhhdCAiZnJlZSIgc3BhY2UgaXMgb3V0LCB0aGUgc3BhY2UKICogZ2V0cyBncm93biBhbmQgcmdrbi0+c2l6ZSBnZXRzIGFkanVzdGVkLgogKgogKiB0aGVyZSBpcyBhIG9uZSB0byBvbmUgcmVsYXRpb25zaGlwIGJldHdlZW4gZGtlIGFuZCBka2gKICovCiAvKiBrZXkgc3RydWN0LCBvbmNlIHBlciBrZXkgKi8KdHlwZWRlZiBzdHJ1Y3QgewogICAgRFdPUkQJeDE7CQkvKiBGcmVlIGVudHJ5IGluZGljYXRvcig/KSAqLwogICAgRFdPUkQJaGFzaDsJCS8qIHN1bSBvZiBieXRlcyBvZiBrZXluYW1lICovCiAgICBEV09SRAl4MzsJCS8qIFJvb3Qga2V5IGluZGljYXRvcj8gdXN1YWxseSAweEZGRkZGRkZGICovCiAgICBEV09SRAlwcmV2bHZsOwkvKiBvZmZzZXQgb2YgcHJldmlvdXMga2V5ICovCiAgICBEV09SRAluZXh0c3ViOwkvKiBvZmZzZXQgb2YgY2hpbGQga2V5ICovCiAgICBEV09SRAluZXh0OwkJLyogb2Zmc2V0IG9mIHNpYmxpbmcga2V5ICovCiAgICBXT1JECW5yTFM7CQkvKiBpZCBpbnNpZGUgdGhlIHJnZGIgYmxvY2sgKi8KICAgIFdPUkQJbnJNUzsJCS8qIG51bWJlciBvZiB0aGUgcmdkYiBibG9jayAqLwp9IF93OTVka2U7CgovKiBTRUNUSU9OIDM6IGtleSBpbmZvcm1hdGlvbiwgdmFsdWVzIGFuZCBkYXRhCiAqCiAqIHN0cnVjdHVyZToKICogIHNlY3Rpb246CVtibG9ja3NdKgkJKHJlcGVhdCBjcmVnLT5yZ2RiX251bSB0aW1lcykKICogIGJsb2NrczoJW3JnZGJdIFtzdWJibG9ja3NdKiAJKHJlcGVhdCB0aWxsIGJsb2NrIHNpemUgcmVhY2hlZCApCiAqICBzdWJibG9ja3M6CVtka2hdIFtka3ZdKgkJKHJlcGVhdCBka2gtPnZhbHVlcyB0aW1lcyApCiAqCiAqIEFuIGludGVyZXN0aW5nIHJlbGF0aW9uc2hpcCBleGlzdHMgaW4gUkdEQl9zZWN0aW9uLiBUaGUgRFdPUkQgdmFsdWUKICogYXQgb2Zmc2V0IDB4MTAgZXF1YWxzIHRoZSBvbmUgYXQgb2Zmc2V0IDB4MDQgbWludXMgdGhlIG9uZSBhdCBvZmZzZXQgMHgwOC4KICogSSBoYXZlIG5vIGlkZWEgYXQgdGhlIG1vbWVudCB3aGF0IHRoaXMgbWVhbnMuICAoS2V2aW4gQ296ZW5zKQogKi8KCi8qIGJsb2NrIGhlYWRlciwgb25jZSBwZXIgYmxvY2sgKi8KI2RlZmluZSBXOTVfUkVHX1JHREJfSUQJMHg0MjQ0NDc1MgoKdHlwZWRlZiBzdHJ1Y3QgewogICAgRFdPUkQJaWQ7CS8qIDB4MDAgJ1JHREInID0gVzk1X1JFR19SR0RCX0lEICovCiAgICBEV09SRAlzaXplOwkvKiAweDA0ICovCiAgICBEV09SRAl1azE7CS8qIDB4MDggKi8KICAgIERXT1JECXVrMjsJLyogMHgwYyAqLwogICAgRFdPUkQJdWszOwkvKiAweDEwICovCiAgICBEV09SRAl1azQ7CS8qIDB4MTQgKi8KICAgIERXT1JECXVrNTsJLyogMHgxOCAqLwogICAgRFdPUkQJdWs2OwkvKiAweDFjICovCiAgICAvKiBka2ggKi8KfSBfdzk1cmdkYjsKCi8qIERpc2sgS2V5IEhlYWRlciBzdHJ1Y3R1cmUgKFJHREIgcGFydCksIG9uY2UgcGVyIGtleSAqLwp0eXBlZGVmCXN0cnVjdCB7CiAgICBEV09SRAluZXh0a2V5b2ZmOyAJLyogMHgwMCBvZmZzZXQgdG8gbmV4dCBka2ggKi8KICAgIFdPUkQJbnJMUzsJCS8qIDB4MDQgaWQgaW5zaWRlIHRoZSByZ2RiIGJsb2NrICovCiAgICBXT1JECW5yTVM7CQkvKiAweDA2IG51bWJlciBvZiB0aGUgcmdkYiBibG9jayAqLwogICAgRFdPUkQJYnl0ZXN1c2VkOwkvKiAweDA4ICovCiAgICBXT1JECWtleW5hbWVsZW47CS8qIDB4MGMgbGVuIG9mIG5hbWUgKi8KICAgIFdPUkQJdmFsdWVzOwkJLyogMHgwZSBudW1iZXIgb2YgdmFsdWVzICovCiAgICBEV09SRAl4eDE7CQkvKiAweDEwICovCiAgICBjaGFyCW5hbWVbMV07CS8qIDB4MTQgKi8KICAgIC8qIGRrdiAqLwkJLyogMHgxNCArIGtleW5hbWVsZW4gKi8KfSBfdzk1ZGtoOwoKLyogRGlzayBLZXkgVmFsdWUgc3RydWN0dXJlLCBvbmNlIHBlciB2YWx1ZSAqLwp0eXBlZGVmCXN0cnVjdCB7CiAgICBEV09SRAl0eXBlOwkJLyogMHgwMCAqLwogICAgRFdPUkQJeDE7CQkvKiAweDA0ICovCiAgICBXT1JECXZhbG5hbWVsZW47CS8qIDB4MDggbGVuZ3RoIG9mIG5hbWUsIDAgaXMgZGVmYXVsdCBrZXkgKi8KICAgIFdPUkQJdmFsZGF0YWxlbjsJLyogMHgwQSBsZW5ndGggb2YgZGF0YSAqLwogICAgY2hhcgluYW1lWzFdOwkvKiAweDBjICovCiAgICAvKiByYXcgZGF0YSAqLwkJLyogMHgwYyArIHZhbG5hbWVsZW4gKi8KfSBfdzk1ZGt2OwoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBfdzk1X2xvb2t1cF9ka2ggW0ludGVybmFsXQogKgogKiBzZWVrcyB0aGUgZGtoIGJlbG9uZ2luZyB0byBhIGRrZQogKi8Kc3RhdGljIF93OTVka2ggKl93OTVfbG9va3VwX2RraChfdzk1Y3JlZyAqY3JlZyxpbnQgbnJMUyxpbnQgbnJNUykKewogICAgX3c5NXJnZGIgKiByZ2RiOwogICAgX3c5NWRraCAqIGRraDsKICAgIGludCBpOwoKICAgIC8qIGdldCB0aGUgYmVnaW5uaW5nIG9mIHRoZSByZ2RiIGRhdGFzdG9yZSAqLwogICAgcmdkYiA9IChfdzk1cmdkYiopKChjaGFyKiljcmVnK2NyZWctPnJnZGJfb2ZmKTsKCiAgICAvKiBjaGVjazogcmVxdWVzdGVkIGJsb2NrIDwgbGFzdF9ibG9jaykgKi8KICAgIGlmIChjcmVnLT5yZ2RiX251bSA8PSBuck1TKSB7CiAgICAgICAgRVJSKCJyZWdpc3RyeSBmaWxlIGNvcnJ1cHQhIHJlcXVlc3RlZCBibG9jayBuby4gYmV5b25kIGVuZC5cbiIpOwogICAgICAgIGdvdG8gZXJyb3I7CiAgICB9CgogICAgLyogZmluZCB0aGUgcmlnaHQgYmxvY2sgKi8KICAgIGZvcihpPTA7IGk8bnJNUyA7aSsrKSB7CiAgICAgICAgaWYocmdkYi0+aWQgIT0gVzk1X1JFR19SR0RCX0lEKSB7ICAvKiBjaGVjayB0aGUgbWFnaWMgKi8KICAgICAgICAgICAgRVJSKCJyZWdpc3RyeSBmaWxlIGNvcnJ1cHQhIGJhZCBtYWdpYyAweCUwOGx4XG4iLCByZ2RiLT5pZCk7CiAgICAgICAgICAgIGdvdG8gZXJyb3I7CiAgICAgICAgfQogICAgICAgIHJnZGIgPSAoX3c5NXJnZGIqKSAoKGNoYXIqKXJnZGIrcmdkYi0+c2l6ZSk7CQkvKiBmaW5kIG5leHQgYmxvY2sgKi8KICAgIH0KCiAgICBka2ggPSAoX3c5NWRraCopKHJnZGIgKyAxKTsJCQkJLyogZmlyc3Qgc3ViIGJsb2NrIHdpdGhpbiB0aGUgcmdkYiAqLwoKICAgIGRvIHsKICAgICAgICBpZihuckxTPT1ka2gtPm5yTFMgKSByZXR1cm4gZGtoOwogICAgICAgIGRraCA9IChfdzk1ZGtoKikoKGNoYXIqKWRraCArIGRraC0+bmV4dGtleW9mZik7CS8qIGZpbmQgbmV4dCBzdWJibG9jayAqLwogICAgfSB3aGlsZSAoKGNoYXIgKilka2ggPCAoKGNoYXIqKXJnZGIrcmdkYi0+c2l6ZSkpOwoKZXJyb3I6CiAgICByZXR1cm4gTlVMTDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBfdzk1X2R1bXBfZGt2IFtJbnRlcm5hbF0KICovCnN0YXRpYyBpbnQgX3c5NV9kdW1wX2Rrdihfdzk1ZGtoICpka2gsaW50IG5yTFMsaW50IG5yTVMsRklMRSAqZikKewogICAgX3c5NWRrdiAqIGRrdjsKICAgIGludCBpOwoKICAgIC8qIGZpcnN0IHZhbHVlIGJsb2NrICovCiAgICBka3YgPSAoX3c5NWRrdiopKChjaGFyKilka2grZGtoLT5rZXluYW1lbGVuKzB4MTQpOwoKICAgIC8qIGxvb3AgdGhyb3VnaCB0aGUgdmFsdWVzICovCiAgICBmb3IgKGk9MDsgaTwgZGtoLT52YWx1ZXM7IGkrKykgewogICAgICAgIHN0cnVjdCBrZXlfdmFsdWUgdmFsdWU7CiAgICAgICAgV0NIQVIgKnBkYXRhOwoKICAgICAgICB2YWx1ZS5uYW1lVyA9IF9zdHJkdXBuQXRvVyhka3YtPm5hbWUsZGt2LT52YWxuYW1lbGVuKTsKICAgICAgICB2YWx1ZS50eXBlID0gZGt2LT50eXBlOwogICAgICAgIHZhbHVlLmxlbiA9IGRrdi0+dmFsZGF0YWxlbjsKCiAgICAgICAgdmFsdWUuZGF0YSA9ICYoZGt2LT5uYW1lW2Rrdi0+dmFsbmFtZWxlbl0pOwogICAgICAgIHBkYXRhID0gTlVMTDsKICAgICAgICBpZiAoICh2YWx1ZS50eXBlPT1SRUdfU1opIHx8ICh2YWx1ZS50eXBlPT1SRUdfRVhQQU5EX1NaKSB8fCAodmFsdWUudHlwZT09UkVHX01VTFRJX1NaKSApIHsKICAgICAgICAgICAgcGRhdGEgPSBfc3RyZHVwbkF0b1codmFsdWUuZGF0YSx2YWx1ZS5sZW4pOwogICAgICAgICAgICB2YWx1ZS5sZW4gKj0gMjsKICAgICAgICB9CiAgICAgICAgaWYgKHBkYXRhICE9IE5VTEwpIHZhbHVlLmRhdGEgPSBwZGF0YTsKCiAgICAgICAgX2R1bXBfdmFsdWUoJnZhbHVlLGYpOwogICAgICAgIGZyZWUodmFsdWUubmFtZVcpOwogICAgICAgIGlmIChwZGF0YSAhPSBOVUxMKSBmcmVlKHBkYXRhKTsKCiAgICAgICAgLyogbmV4dCB2YWx1ZSAqLwogICAgICAgIGRrdiA9IChfdzk1ZGt2KikoKGNoYXIqKWRrditka3YtPnZhbG5hbWVsZW4rZGt2LT52YWxkYXRhbGVuKzB4MGMpOwogICAgfQogICAgcmV0dXJuIFRSVUU7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogX3c5NV9kdW1wX2RrZSBbSW50ZXJuYWxdCiAqLwpzdGF0aWMgaW50IF93OTVfZHVtcF9ka2UoTFBTVFIga2V5X25hbWUsX3c5NWNyZWcgKmNyZWcsX3c5NXJna24gKnJna24sX3c5NWRrZSAqZGtlLEZJTEUgKmYsaW50IGxldmVsKQp7CiAgICBfdzk1ZGtoICogZGtoOwogICAgTFBTVFIgbmV3X2tleV9uYW1lID0gTlVMTDsKCiAgICAvKiBzcGVjaWFsIHJvb3Qga2V5ICovCiAgICBpZiAoZGtlLT5uckxTID09IDB4ZmZmZiB8fCBka2UtPm5yTVM9PTB4ZmZmZikJCS8qIGVnLiB0aGUgcm9vdCBrZXkgaGFzIG5vIG5hbWUgKi8KICAgIHsKICAgICAgICAvKiBwYXJzZSB0aGUgb25lIHN1YmtleSAqLwogICAgICAgIGlmIChka2UtPm5leHRzdWIgIT0gMHhmZmZmZmZmZikgcmV0dXJuIF93OTVfZHVtcF9ka2Uoa2V5X25hbWUsIGNyZWcsIHJna24sIChfdzk1ZGtlKikoKGNoYXIqKXJna24rZGtlLT5uZXh0c3ViKSxmLGxldmVsKTsKICAgICAgICAvKiBoYXMgbm8gc2libGluZyBrZXlzICovCiAgICAgICAgcmV0dXJuIEZBTFNFOwogICAgfQoKICAgIC8qIHNlYXJjaCBzdWJibG9jayAqLwogICAgaWYgKCEoZGtoID0gX3c5NV9sb29rdXBfZGtoKGNyZWcsIGRrZS0+bnJMUywgZGtlLT5uck1TKSkpIHsKICAgICAgICBFUlIoImRrZSBwb2ludGluZyB0byBtaXNzaW5nIGRraCAhXG4iKTsKICAgICAgICByZXR1cm4gRkFMU0U7CiAgICB9CgogICAgaWYgKGxldmVsIDw9IDApIHsKICAgICAgICAvKiBjcmVhdGUgbmV3IHN1YmtleSBuYW1lICovCiAgICAgICAgbmV3X2tleV9uYW1lID0gX3N0cmR1cG5BKGtleV9uYW1lLHN0cmxlbihrZXlfbmFtZSkrZGtoLT5rZXluYW1lbGVuKzEpOwogICAgICAgIGlmIChzdHJjbXAobmV3X2tleV9uYW1lLCIiKSAhPSAwKSBzdHJjYXQobmV3X2tleV9uYW1lLCJcXCIpOwogICAgICAgIHN0cm5jYXQobmV3X2tleV9uYW1lLGRraC0+bmFtZSxka2gtPmtleW5hbWVsZW4pOwoKICAgICAgICAvKiB3YWxrIHNpYmxpbmcga2V5cyAqLwogICAgICAgIGlmIChka2UtPm5leHQgIT0gMHhmZmZmZmZmZiApIHsKICAgICAgICAgICAgaWYgKCFfdzk1X2R1bXBfZGtlKGtleV9uYW1lLCBjcmVnLCByZ2tuLCAoX3c5NWRrZSopKChjaGFyKilyZ2tuK2RrZS0+bmV4dCksZixsZXZlbCkpIHsKICAgICAgICAgICAgICAgIGZyZWUobmV3X2tleV9uYW1lKTsKICAgICAgICAgICAgICAgIHJldHVybiBGQUxTRTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgLyogd3JpdGUgdGhlIGtleSBwYXRoIChzb21ldGhpbmcgbGlrZSBbU29mdHdhcmVcXE1pY3Jvc29mdFxcLi5dKSBvbmx5IGlmOgogICAgICAgICAgIDEpIGtleSBoYXMgc29tZSB2YWx1ZXMKICAgICAgICAgICAyKSBrZXkgaGFzIG5vIHZhbHVlcyBhbmQgbm8gc3Via2V5cwogICAgICAgICovCiAgICAgICAgaWYgKGRraC0+dmFsdWVzID4gMCkgewogICAgICAgICAgICAvKiB0aGVyZSBhcmUgc29tZSB2YWx1ZXMgKi8KICAgICAgICAgICAgZnByaW50ZihmLCJcblsiKTsKICAgICAgICAgICAgX2R1bXBfc3RyQXRvVyhuZXdfa2V5X25hbWUsc3RybGVuKG5ld19rZXlfbmFtZSksZiwiW10iKTsKICAgICAgICAgICAgZnByaW50ZihmLCJdXG4iKTsKICAgICAgICAgICAgaWYgKCFfdzk1X2R1bXBfZGt2KGRraCwgZGtlLT5uckxTLCBka2UtPm5yTVMsZikpIHsKICAgICAgICAgICAgICBmcmVlKG5ld19rZXlfbmFtZSk7CiAgICAgICAgICAgICAgcmV0dXJuIEZBTFNFOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGlmICgoZGtlLT5uZXh0c3ViID09IDB4ZmZmZmZmZmYpICYmIChka2gtPnZhbHVlcyA9PSAwKSkgewogICAgICAgICAgICAvKiBubyBzdWJrZXlzIGFuZCBubyB2YWx1ZXMgKi8KICAgICAgICAgICAgZnByaW50ZihmLCJcblsiKTsKICAgICAgICAgICAgX2R1bXBfc3RyQXRvVyhuZXdfa2V5X25hbWUsc3RybGVuKG5ld19rZXlfbmFtZSksZiwiW10iKTsKICAgICAgICAgICAgZnByaW50ZihmLCJdXG4iKTsKICAgICAgICB9CiAgICB9IGVsc2UgbmV3X2tleV9uYW1lID0gX3N0cmR1cG5BKGtleV9uYW1lLHN0cmxlbihrZXlfbmFtZSkpOwoKICAgIC8qIG5leHQgc3ViIGtleSAqLwogICAgaWYgKGRrZS0+bmV4dHN1YiAhPSAweGZmZmZmZmZmKSB7CiAgICAgICAgaWYgKCFfdzk1X2R1bXBfZGtlKG5ld19rZXlfbmFtZSwgY3JlZywgcmdrbiwgKF93OTVka2UqKSgoY2hhciopcmdrbitka2UtPm5leHRzdWIpLGYsbGV2ZWwtMSkpIHsKICAgICAgICAgIGZyZWUobmV3X2tleV9uYW1lKTsKICAgICAgICAgIHJldHVybiBGQUxTRTsKICAgICAgICB9CiAgICB9CgogICAgZnJlZShuZXdfa2V5X25hbWUpOwogICAgcmV0dXJuIFRSVUU7Cn0KLyogZW5kIHdpbmRvd3MgOTUgbG9hZGVyICovCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCi8qICAgICAgICAgICAgICAgICAgICAgICAgd2luZG93cyBOVCByZWdpc3RyeSBsb2FkZXIgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKi8KLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKLyogTlQgUkVHSVNUUlkgTE9BREVSICovCgojaWZkZWYgSEFWRV9TWVNfTU1BTl9ICiMgaW5jbHVkZSA8c3lzL21tYW4uaD4KI2VuZGlmCgojaWZuZGVmIE1BUF9GQUlMRUQKI2RlZmluZSBNQVBfRkFJTEVEICgoTFBWT0lEKS0xKQojZW5kaWYKCiNkZWZpbmUgTlRfUkVHX0JMT0NLX1NJWkUgICAgICAgICAgICAweDEwMDAKCiNkZWZpbmUgTlRfUkVHX0hFQURFUl9CTE9DS19JRCAgICAgICAweDY2Njc2NTcyCS8qIHJlZ2YgKi8KI2RlZmluZSBOVF9SRUdfUE9PTF9CTE9DS19JRCAgICAgICAgIDB4NkU2OTYyNjgJLyogaGJpbiAqLwojZGVmaW5lIE5UX1JFR19LRVlfQkxPQ0tfSUQgICAgICAgICAgMHg2YjZlIC8qIG5rICovCiNkZWZpbmUgTlRfUkVHX1ZBTFVFX0JMT0NLX0lEICAgICAgICAweDZiNzYgLyogdmsgKi8KCi8qIHN1YmJsb2NrcyBvZiBuayAqLwojZGVmaW5lIE5UX1JFR19IQVNIX0JMT0NLX0lEICAgICAgICAgMHg2NjZjIC8qIGxmICovCiNkZWZpbmUgTlRfUkVHX05PSEFTSF9CTE9DS19JRCAgICAgICAweDY5NmMgLyogbGkgKi8KI2RlZmluZSBOVF9SRUdfUklfQkxPQ0tfSUQJICAgICAweDY5NzIgLyogcmkgKi8KCiNkZWZpbmUgTlRfUkVHX0tFWV9CTE9DS19UWVBFICAgICAgICAweDIwCiNkZWZpbmUgTlRfUkVHX1JPT1RfS0VZX0JMT0NLX1RZUEUgICAweDJjCgp0eXBlZGVmIHN0cnVjdCB7CiAgICBEV09SRAlpZDsJCS8qIDB4NjY2NzY1NzIgJ3JlZ2YnKi8KICAgIERXT1JECXVrMTsJCS8qIDB4MDQgKi8KICAgIERXT1JECXVrMjsJCS8qIDB4MDggKi8KICAgIEZJTEVUSU1FCURhdGVNb2RpZmllZDsJLyogMHgwYyAqLwogICAgRFdPUkQJdWszOwkJLyogMHgxNCAqLwogICAgRFdPUkQJdWs0OwkJLyogMHgxOCAqLwogICAgRFdPUkQJdWs1OwkJLyogMHgxYyAqLwogICAgRFdPUkQJdWs2OwkJLyogMHgyMCAqLwogICAgRFdPUkQJUm9vdEtleUJsb2NrOwkvKiAweDI0ICovCiAgICBEV09SRAlCbG9ja1NpemU7CS8qIDB4MjggKi8KICAgIERXT1JEICAgdWs3WzExNl07CiAgICBEV09SRAlDaGVja3N1bTsgLyogYXQgb2Zmc2V0IDB4MUZDICovCn0gbnRfcmVnZjsKCnR5cGVkZWYgc3RydWN0IHsKICAgIERXT1JECWJsb2Nrc2l6ZTsKICAgIEJZVEUJZGF0YVsxXTsKfSBudF9oYmluX3N1YjsKCnR5cGVkZWYgc3RydWN0IHsKICAgIERXT1JECWlkOwkJLyogMHg2RTY5NjI2OCAnaGJpbicgKi8KICAgIERXT1JECW9mZl9wcmV2OwogICAgRFdPUkQJb2ZmX25leHQ7CiAgICBEV09SRAl1azE7CiAgICBEV09SRAl1azI7CQkvKiAweDEwICovCiAgICBEV09SRAl1azM7CQkvKiAweDE0ICovCiAgICBEV09SRAl1azQ7CQkvKiAweDE4ICovCiAgICBEV09SRAlzaXplOwkJLyogMHgxQyAqLwogICAgbnRfaGJpbl9zdWIJaGJpbl9zdWI7CS8qIDB4MjAgKi8KfSBudF9oYmluOwoKLyoKICogdGhlIHZhbHVlX2xpc3QgY29uc2lzdHMgb2Ygb2Zmc2V0cyB0byB0aGUgdmFsdWVzICh2aykKICovCnR5cGVkZWYgc3RydWN0IHsKICAgIFdPUkQJU3ViQmxvY2tJZDsJCS8qIDB4MDAgMHg2QjZFICovCiAgICBXT1JECVR5cGU7CQkJLyogMHgwMiBmb3IgdGhlIHJvb3Qta2V5OiAweDJDLCBvdGhlcndpc2UgMHgyMCovCiAgICBGSUxFVElNRQl3cml0ZXRpbWU7CS8qIDB4MDQgKi8KICAgIERXT1JECXVrMTsJCQkvKiAweDBDICovCiAgICBEV09SRAlwYXJlbnRfb2ZmOwkJLyogMHgxMCBPZmZzZXQgb2YgT3duZXIvUGFyZW50IGtleSAqLwogICAgRFdPUkQJbnJfc3Via2V5czsJCS8qIDB4MTQgbnVtYmVyIG9mIHN1Yi1LZXlzICovCiAgICBEV09SRAl1azg7CQkJLyogMHgxOCAqLwogICAgRFdPUkQJbGZfb2ZmOwkJCS8qIDB4MUMgT2Zmc2V0IG9mIHRoZSBzdWIta2V5IGxmLVJlY29yZHMgKi8KICAgIERXT1JECXVrMjsJCQkvKiAweDIwICovCiAgICBEV09SRAlucl92YWx1ZXM7CQkvKiAweDI0IG51bWJlciBvZiB2YWx1ZXMgKi8KICAgIERXT1JECXZhbHVlbGlzdF9vZmY7CQkvKiAweDI4IE9mZnNldCBvZiB0aGUgVmFsdWUtTGlzdCAqLwogICAgRFdPUkQJb2ZmX3NrOwkJCS8qIDB4MmMgT2Zmc2V0IG9mIHRoZSBzay1SZWNvcmQgKi8KICAgIERXT1JECW9mZl9jbGFzczsJCS8qIDB4MzAgT2Zmc2V0IG9mIHRoZSBDbGFzcy1OYW1lICovCiAgICBEV09SRAl1azM7CQkJLyogMHgzNCAqLwogICAgRFdPUkQJdWs0OwkJCS8qIDB4MzggKi8KICAgIERXT1JECXVrNTsJCQkvKiAweDNjICovCiAgICBEV09SRAl1azY7CQkJLyogMHg0MCAqLwogICAgRFdPUkQJdWs3OwkJCS8qIDB4NDQgKi8KICAgIFdPUkQJbmFtZV9sZW47CQkvKiAweDQ4IG5hbWUtbGVuZ3RoICovCiAgICBXT1JECWNsYXNzX2xlbjsJCS8qIDB4NGEgY2xhc3MtbmFtZSBsZW5ndGggKi8KICAgIGNoYXIJbmFtZVsxXTsJCS8qIDB4NGMga2V5LW5hbWUgKi8KfSBudF9uazsKCnR5cGVkZWYgc3RydWN0IHsKICAgIERXT1JECW9mZl9uazsJLyogMHgwMCAqLwogICAgRFdPUkQJbmFtZTsJLyogMHgwNCAqLwp9IGhhc2hfcmVjOwoKdHlwZWRlZiBzdHJ1Y3QgewogICAgV09SRAlpZDsJCS8qIDB4MDAgMHg2NjZjICovCiAgICBXT1JECW5yX2tleXM7CS8qIDB4MDYgKi8KICAgIGhhc2hfcmVjCWhhc2hfcmVjWzFdOwp9IG50X2xmOwoKLyoKIGxpc3Qgb2Ygc3Via2V5cyB3aXRob3V0IGhhc2gKCiBsaSAtLSstLT5uawogICAgICB8CiAgICAgICstLT5uawogKi8KdHlwZWRlZiBzdHJ1Y3QgewogICAgV09SRAlpZDsJCS8qIDB4MDAgMHg2OTZjICovCiAgICBXT1JECW5yX2tleXM7CiAgICBEV09SRAlvZmZfbmtbMV07Cn0gbnRfbGk7CgovKgogdGhpcyBpcyBhIGludGVybWVkaWF0ZSBub2RlCgogcmkgLS0rLS0+bGktLSstLT5uawogICAgICB8ICAgICAgICsKICAgICAgfCAgICAgICArLS0+bmsKICAgICAgfAogICAgICArLS0+bGktLSstLT5uawogICAgICAgICAgICAgICsKCSAgICAgICstLT5uawogKi8KdHlwZWRlZiBzdHJ1Y3QgewogICAgV09SRAlpZDsJCS8qIDB4MDAgMHg2OTcyICovCiAgICBXT1JECW5yX2xpOwkJLyogMHgwMiBudW1iZXIgb2ZmIG9mZnNldHMgKi8KICAgIERXT1JECW9mZl9saVsxXTsJLyogMHgwNCBwb2ludHMgdG8gbGkgKi8KfSBudF9yaTsKCnR5cGVkZWYgc3RydWN0IHsKICAgIFdPUkQJaWQ7CQkvKiAweDAwICd2aycgKi8KICAgIFdPUkQJbmFtX2xlbjsKICAgIERXT1JECWRhdGFfbGVuOwogICAgRFdPUkQJZGF0YV9vZmY7CiAgICBEV09SRAl0eXBlOwogICAgV09SRAlmbGFnOwogICAgV09SRAl1azE7CiAgICBjaGFyCW5hbWVbMV07Cn0gbnRfdms7CgovKgogKiBnZXRzIGEgdmFsdWUKICoKICogdmstPmZsYWc6CiAqICAwIHZhbHVlIGlzIGEgZGVmYXVsdCB2YWx1ZQogKiAgMSB0aGUgdmFsdWUgaGFzIGEgbmFtZQogKgogKiB2ay0+ZGF0YV9sZW4KICogIGxlbiBvZiB0aGUgd2hvbGUgZGF0YSBibG9jawogKiAgLSByZWdfc3ogKHVuaWNvZGUpCiAqICAgIGJ5dGVzIGluY2x1ZGluZyB0aGUgdGVybWluYXRpbmcgXDAgPSAyKihudW1iZXJfb2ZfY2hhcnMrMSkKICogIC0gcmVnX2R3b3JkLCByZWdfYmluYXJ5OgogKiAgICBpZiBoaWdoZXN0IGJpdCBvZiBkYXRhX2xlbiBpcyBzZXQgZGF0YV9vZmYgY29udGFpbnMgdGhlIHZhbHVlCiAqLwpzdGF0aWMgaW50IF9udF9kdW1wX3ZrKExQU1RSIGtleV9uYW1lLCBjaGFyICpiYXNlLCBudF92ayAqdmssRklMRSAqZikKewogICAgQllURSAqcGRhdGEgPSAoQllURSAqKShiYXNlK3ZrLT5kYXRhX29mZis0KTsgLyogc3RhcnQgb2YgZGF0YSAqLwogICAgc3RydWN0IGtleV92YWx1ZSB2YWx1ZTsKCiAgICBpZiAodmstPmlkICE9IE5UX1JFR19WQUxVRV9CTE9DS19JRCkgewogICAgICAgIEVSUigidW5rbm93biBibG9jayBmb3VuZCAoMHglMDR4KSwgcGxlYXNlIHJlcG9ydCFcbiIsIHZrLT5pZCk7CiAgICAgICAgcmV0dXJuIEZBTFNFOwogICAgfQoKICAgIHZhbHVlLm5hbWVXID0gX3N0cmR1cG5BdG9XKHZrLT5uYW1lLHZrLT5uYW1fbGVuKTsKICAgIHZhbHVlLnR5cGUgPSB2ay0+dHlwZTsKICAgIHZhbHVlLmxlbiA9ICh2ay0+ZGF0YV9sZW4gJiAweDdmZmZmZmZmKTsKICAgIHZhbHVlLmRhdGEgPSAodmstPmRhdGFfbGVuICYgMHg4MDAwMDAwMCkgPyAoTFBCWVRFKSYodmstPmRhdGFfb2ZmKTogcGRhdGE7CgogICAgX2R1bXBfdmFsdWUoJnZhbHVlLGYpOwogICAgZnJlZSh2YWx1ZS5uYW1lVyk7CgogICAgcmV0dXJuIFRSVUU7Cn0KCi8qIGl0J3MgY2FsbGVkIGZyb20gX250X2R1bXBfbGYoKSAqLwpzdGF0aWMgaW50IF9udF9kdW1wX25rKExQU1RSIGtleV9uYW1lLGNoYXIgKmJhc2UsbnRfbmsgKm5rLEZJTEUgKmYsaW50IGxldmVsKTsKCi8qCiAqIGdldCB0aGUgc3Via2V5cwogKgogKiB0aGlzIHN0cnVjdHVyZSBjb250YWlucyB0aGUgaGFzaCBvZiBhIGtleW5hbWUgYW5kIHBvaW50cyB0byBhbGwKICogc3Via2V5cwogKgogKiBleGNlcHRpb246IGlmIHRoZSBpZCBpcyAnaWwnIHRoZXJlIGFyZSBubyBoYXNoIHZhbHVlcyBhbmQgZXZlcnkKICogZHdvcmQgaXMgYSBvZmZzZXQKICovCnN0YXRpYyBpbnQgX250X2R1bXBfbGYoTFBTVFIga2V5X25hbWUsIGNoYXIgKmJhc2UsIGludCBzdWJrZXlzLCBudF9sZiAqbGYsIEZJTEUgKmYsIGludCBsZXZlbCkKewogICAgaW50IGk7CgogICAgaWYgKGxmLT5pZCA9PSBOVF9SRUdfSEFTSF9CTE9DS19JRCkgewogICAgICAgIGlmIChzdWJrZXlzICE9IGxmLT5ucl9rZXlzKSBnb3RvIGVycm9yMTsKCiAgICAgICAgZm9yIChpPTA7IGk8bGYtPm5yX2tleXM7IGkrKykKICAgICAgICAgICAgaWYgKCFfbnRfZHVtcF9uayhrZXlfbmFtZSwgYmFzZSwgKG50X25rKikoYmFzZStsZi0+aGFzaF9yZWNbaV0ub2ZmX25rKzQpLCBmLCBsZXZlbCkpIGdvdG8gZXJyb3I7CiAgICB9IGVsc2UgaWYgKGxmLT5pZCA9PSBOVF9SRUdfTk9IQVNIX0JMT0NLX0lEKSB7CiAgICAgICAgbnRfbGkgKiBsaSA9IChudF9saSopbGY7CiAgICAgICAgaWYgKHN1YmtleXMgIT0gbGktPm5yX2tleXMpIGdvdG8gZXJyb3IxOwoKICAgICAgICBmb3IgKGk9MDsgaTxsaS0+bnJfa2V5czsgaSsrKQogICAgICAgICAgICBpZiAoIV9udF9kdW1wX25rKGtleV9uYW1lLCBiYXNlLCAobnRfbmsqKShiYXNlK2xpLT5vZmZfbmtbaV0rNCksIGYsIGxldmVsKSkgZ290byBlcnJvcjsKICAgIH0gZWxzZSBpZiAobGYtPmlkID09IE5UX1JFR19SSV9CTE9DS19JRCkgeyAgLyogcmkgKi8KICAgICAgICBudF9yaSAqIHJpID0gKG50X3JpKilsZjsKICAgICAgICBpbnQgbGlfc3Via2V5cyA9IDA7CgogICAgICAgIC8qIGNvdW50IGFsbCBzdWJrZXlzICovCiAgICAgICAgZm9yIChpPTA7IGk8cmktPm5yX2xpOyBpKyspIHsKICAgICAgICAgICAgbnRfbGkgKiBsaSA9IChudF9saSopKGJhc2UrcmktPm9mZl9saVtpXSs0KTsKICAgICAgICAgICAgaWYobGktPmlkICE9IE5UX1JFR19OT0hBU0hfQkxPQ0tfSUQpIGdvdG8gZXJyb3IyOwogICAgICAgICAgICBsaV9zdWJrZXlzICs9IGxpLT5ucl9rZXlzOwogICAgICAgIH0KCiAgICAgICAgLyogY2hlY2sgbnVtYmVyICovCiAgICAgICAgaWYgKHN1YmtleXMgIT0gbGlfc3Via2V5cykgZ290byBlcnJvcjE7CgogICAgICAgIC8qIGxvb3AgdGhyb3VnaCB0aGUga2V5cyAqLwogICAgICAgIGZvciAoaT0wOyBpPHJpLT5ucl9saTsgaSsrKSB7CiAgICAgICAgICAgIG50X2xpICpsaSA9IChudF9saSopKGJhc2UrcmktPm9mZl9saVtpXSs0KTsKICAgICAgICAgICAgaWYgKCFfbnRfZHVtcF9sZihrZXlfbmFtZSwgYmFzZSwgbGktPm5yX2tleXMsIChudF9sZiopbGksIGYsIGxldmVsKSkgZ290byBlcnJvcjsKICAgICAgICB9CiAgICB9IGVsc2UgZ290byBlcnJvcjI7CgogICAgcmV0dXJuIFRSVUU7CgplcnJvcjI6CiAgICBpZiAobGYtPmlkID09IDB4Njg2YykKICAgICAgICBGSVhNRSgidW5rbm93biBXaW4gWFAgbm9kZSBpZCAweDY4NmM6IGRvIHdlIG5lZWQgdG8gYWRkIHN1cHBvcnQgZm9yIGl0ID9cbiIpOwogICAgZWxzZQogICAgICAgIEVSUigidW5rbm93biBub2RlIGlkIDB4JTA0eCwgcGxlYXNlIHJlcG9ydCFcbiIsIGxmLT5pZCk7CiAgICByZXR1cm4gVFJVRTsKCmVycm9yMToKICAgIEVSUigicmVnaXN0cnkgZmlsZSBjb3JydXB0ISAoaW5jb25zaXN0ZW50IG51bWJlciBvZiBzdWJrZXlzKVxuIik7CiAgICByZXR1cm4gRkFMU0U7CgplcnJvcjoKICAgIEVSUigiZXJyb3IgcmVhZGluZyBsZiBibG9ja1xuIik7CiAgICByZXR1cm4gRkFMU0U7Cn0KCi8qIF9udF9kdW1wX25rIFtJbnRlcm5hbF0gKi8Kc3RhdGljIGludCBfbnRfZHVtcF9uayhMUFNUUiBrZXlfbmFtZSxjaGFyICpiYXNlLG50X25rICpuayxGSUxFICpmLGludCBsZXZlbCkKewogICAgdW5zaWduZWQgaW50IG47CiAgICBEV09SRCAqdmw7CiAgICBMUFNUUiBuZXdfa2V5X25hbWUgPSBOVUxMOwoKICAgIFRSQUNFKCIlc1xuIiwga2V5X25hbWUpOwoKICAgIGlmIChuay0+U3ViQmxvY2tJZCAhPSBOVF9SRUdfS0VZX0JMT0NLX0lEKSB7CiAgICAgICAgRVJSKCJ1bmtub3duIG5vZGUgaWQgMHglMDR4LCBwbGVhc2UgcmVwb3J0IVxuIiwgbmstPlN1YkJsb2NrSWQpOwogICAgICAgIHJldHVybiBGQUxTRTsKICAgIH0KCiAgICBpZiAoKG5rLT5UeXBlIT1OVF9SRUdfUk9PVF9LRVlfQkxPQ0tfVFlQRSkgJiYgKCgobnRfbmsqKShiYXNlK25rLT5wYXJlbnRfb2ZmKzQpKS0+U3ViQmxvY2tJZCAhPSBOVF9SRUdfS0VZX0JMT0NLX0lEKSkgewogICAgICAgIEVSUigicmVnaXN0cnkgZmlsZSBjb3JydXB0IVxuIik7CiAgICAgICAgcmV0dXJuIEZBTFNFOwogICAgfQoKICAgIC8qIGNyZWF0ZSB0aGUgbmV3IGtleSAqLwogICAgaWYgKGxldmVsIDw9IDApIHsKICAgICAgICAvKiBjcmVhdGUgbmV3IHN1YmtleSBuYW1lICovCiAgICAgICAgbmV3X2tleV9uYW1lID0gX3N0cmR1cG5BKGtleV9uYW1lLHN0cmxlbihrZXlfbmFtZSkrbmstPm5hbWVfbGVuKzEpOwogICAgICAgIGlmIChzdHJjbXAobmV3X2tleV9uYW1lLCIiKSAhPSAwKSBzdHJjYXQobmV3X2tleV9uYW1lLCJcXCIpOwogICAgICAgIHN0cm5jYXQobmV3X2tleV9uYW1lLG5rLT5uYW1lLG5rLT5uYW1lX2xlbik7CgogICAgICAgIC8qIHdyaXRlIHRoZSBrZXkgcGF0aCAoc29tZXRoaW5nIGxpa2UgW1NvZnR3YXJlXFxNaWNyb3NvZnRcXC4uXSkgb25seSBpZjoKICAgICAgICAgICAxKSBrZXkgaGFzIHNvbWUgdmFsdWVzCiAgICAgICAgICAgMikga2V5IGhhcyBubyB2YWx1ZXMgYW5kIG5vIHN1YmtleXMKICAgICAgICAqLwogICAgICAgIGlmIChuay0+bnJfdmFsdWVzID4gMCkgewogICAgICAgICAgICAvKiB0aGVyZSBhcmUgc29tZSB2YWx1ZXMgKi8KICAgICAgICAgICAgZnByaW50ZihmLCJcblsiKTsKICAgICAgICAgICAgX2R1bXBfc3RyQXRvVyhuZXdfa2V5X25hbWUsc3RybGVuKG5ld19rZXlfbmFtZSksZiwiW10iKTsKICAgICAgICAgICAgZnByaW50ZihmLCJdXG4iKTsKICAgICAgICB9CiAgICAgICAgaWYgKChuay0+bnJfc3Via2V5cyA9PSAwKSAmJiAobmstPm5yX3ZhbHVlcyA9PSAwKSkgewogICAgICAgICAgICAvKiBubyBzdWJrZXlzIGFuZCBubyB2YWx1ZXMgKi8KICAgICAgICAgICAgZnByaW50ZihmLCJcblsiKTsKICAgICAgICAgICAgX2R1bXBfc3RyQXRvVyhuZXdfa2V5X25hbWUsc3RybGVuKG5ld19rZXlfbmFtZSksZiwiW10iKTsKICAgICAgICAgICAgZnByaW50ZihmLCJdXG4iKTsKICAgICAgICB9CgogICAgICAgIC8qIGxvb3AgdHJvdWdoIHRoZSB2YWx1ZSBsaXN0ICovCiAgICAgICAgdmwgPSAoRFdPUkQgKikoYmFzZStuay0+dmFsdWVsaXN0X29mZis0KTsKICAgICAgICBmb3IgKG49MDsgbjxuay0+bnJfdmFsdWVzOyBuKyspIHsKICAgICAgICAgICAgbnRfdmsgKiB2ayA9IChudF92ayopKGJhc2Urdmxbbl0rNCk7CiAgICAgICAgICAgIGlmICghX250X2R1bXBfdmsobmV3X2tleV9uYW1lLCBiYXNlLCB2aywgZikpIHsKICAgICAgICAgICAgICAgIGZyZWUobmV3X2tleV9uYW1lKTsKICAgICAgICAgICAgICAgIHJldHVybiBGQUxTRTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0gZWxzZSBuZXdfa2V5X25hbWUgPSBfc3RyZHVwbkEoa2V5X25hbWUsc3RybGVuKGtleV9uYW1lKSk7CgogICAgLyogbG9vcCB0aHJvdWdoIHRoZSBzdWJrZXlzICovCiAgICBpZiAobmstPm5yX3N1YmtleXMpIHsKICAgICAgICBudF9sZiAqbGYgPSAobnRfbGYqKShiYXNlK25rLT5sZl9vZmYrNCk7CiAgICAgICAgaWYgKCFfbnRfZHVtcF9sZihuZXdfa2V5X25hbWUsIGJhc2UsIG5rLT5ucl9zdWJrZXlzLCBsZiwgZiwgbGV2ZWwtMSkpIHsKICAgICAgICAgICAgZnJlZShuZXdfa2V5X25hbWUpOwogICAgICAgICAgICByZXR1cm4gRkFMU0U7CiAgICAgICAgfQogICAgfQoKICAgIGZyZWUobmV3X2tleV9uYW1lKTsKICAgIHJldHVybiBUUlVFOwp9CgovKiBlbmQgbnQgbG9hZGVyICovCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBfc2V0X3JlZ2lzdHJ5X2xldmVscyBbSW50ZXJuYWxdCiAqCiAqIHNldCBsZXZlbCB0byAwIGZvciBsb2FkaW5nIHN5c3RlbSBmaWxlcwogKiBzZXQgbGV2ZWwgdG8gMSBmb3IgbG9hZGluZyB1c2VyIGZpbGVzCiAqLwpzdGF0aWMgdm9pZCBfc2V0X3JlZ2lzdHJ5X2xldmVscyhpbnQgbGV2ZWwsaW50IHNhdmluZyxpbnQgcGVyaW9kKQp7CiAgICBTRVJWRVJfU1RBUlRfUkVRKCBzZXRfcmVnaXN0cnlfbGV2ZWxzICkKICAgIHsKCXJlcS0+Y3VycmVudCA9IGxldmVsOwoJcmVxLT5zYXZpbmcgID0gc2F2aW5nOwogICAgICAgIHJlcS0+cGVyaW9kICA9IHBlcmlvZDsKICAgICAgICB3aW5lX3NlcnZlcl9jYWxsKCByZXEgKTsKICAgIH0KICAgIFNFUlZFUl9FTkRfUkVROwp9CgovKiBfc2F2ZV9hdF9leGl0IFtJbnRlcm5hbF0gKi8Kc3RhdGljIHZvaWQgX3NhdmVfYXRfZXhpdChIS0VZIGhrZXksTFBDU1RSIHBhdGgpCnsKICAgIExQQ1NUUiBjb25mZGlyID0gd2luZV9nZXRfY29uZmlnX2RpcigpOwoKICAgIFNFUlZFUl9TVEFSVF9SRVEoIHNhdmVfcmVnaXN0cnlfYXRleGl0ICkKICAgIHsKICAgICAgICByZXEtPmhrZXkgPSBoa2V5OwogICAgICAgIHdpbmVfc2VydmVyX2FkZF9kYXRhKCByZXEsIGNvbmZkaXIsIHN0cmxlbihjb25mZGlyKSApOwogICAgICAgIHdpbmVfc2VydmVyX2FkZF9kYXRhKCByZXEsIHBhdGgsIHN0cmxlbihwYXRoKSsxICk7CiAgICAgICAgd2luZV9zZXJ2ZXJfY2FsbCggcmVxICk7CiAgICB9CiAgICBTRVJWRVJfRU5EX1JFUTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBfYWxsb2NhdGVfZGVmYXVsdF9rZXlzIFtJbnRlcm5hbF0KICogUmVnaXN0cnkgaW5pdGlhbGlzYXRpb24sIGFsbG9jYXRlcyBzb21lIGRlZmF1bHQga2V5cy4KICovCnN0YXRpYyB2b2lkIF9hbGxvY2F0ZV9kZWZhdWx0X2tleXModm9pZCkKewogICAgc3RhdGljIGNvbnN0IFdDSEFSIFN0YXREYXRhV1tdID0geydEJywneScsJ24nLCdEJywnYScsJ3QnLCdhJywnXFwnLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdQJywnZScsJ3InLCdmJywnUycsJ3QnLCdhJywndCcsJ3MnLCdcXCcsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ1MnLCd0JywnYScsJ3QnLCdEJywnYScsJ3QnLCdhJywwfTsKICAgIEhLRVkgaGtleTsKICAgIE9CSkVDVF9BVFRSSUJVVEVTIGF0dHI7CiAgICBVTklDT0RFX1NUUklORyBuYW1lVzsKCiAgICBUUkFDRSgiKHZvaWQpXG4iKTsKCiAgICBhdHRyLkxlbmd0aCA9IHNpemVvZihhdHRyKTsKICAgIGF0dHIuUm9vdERpcmVjdG9yeSA9IDA7CiAgICBhdHRyLk9iamVjdE5hbWUgPSAmbmFtZVc7CiAgICBhdHRyLkF0dHJpYnV0ZXMgPSAwOwogICAgYXR0ci5TZWN1cml0eURlc2NyaXB0b3IgPSBOVUxMOwogICAgYXR0ci5TZWN1cml0eVF1YWxpdHlPZlNlcnZpY2UgPSBOVUxMOwoKICAgIFJ0bEluaXRVbmljb2RlU3RyaW5nKCAmbmFtZVcsIFN0YXREYXRhVyApOwogICAgaWYgKCFOdENyZWF0ZUtleSggJmhrZXksIEtFWV9BTExfQUNDRVNTLCAmYXR0ciwgMCwgTlVMTCwgMCwgTlVMTCApKSBOdENsb3NlKCBoa2V5ICk7Cn0KCiNkZWZpbmUgUkVHX0RPTlRMT0FEIC0xCiNkZWZpbmUgUkVHX1dJTjMxICAgICAwCiNkZWZpbmUgUkVHX1dJTjk1ICAgICAxCiNkZWZpbmUgUkVHX1dJTk5UICAgICAyCgovKiByZXR1cm4gdGhlIHR5cGUgb2YgbmF0aXZlIHJlZ2lzdHJ5IFtJbnRlcm5hbF0gKi8Kc3RhdGljIGludCBfZ2V0X3JlZ190eXBlKHZvaWQpCnsKICAgIFdDSEFSIHdpbmRpcltNQVhfUEFUSE5BTUVfTEVOXTsKICAgIFdDSEFSIHRtcFtNQVhfUEFUSE5BTUVfTEVOXTsKICAgIGludCByZXQgPSBSRUdfV0lOMzE7CiAgICBzdGF0aWMgY29uc3QgV0NIQVIgbnRfcmVnX3BhdGhXW10gPSB7J1xcJywncycsJ3knLCdzJywndCcsJ2UnLCdtJywnMycsJzInLCdcXCcsJ2MnLCdvJywnbicsJ2YnLCdpJywnZycsJ1xcJywncycsJ3knLCdzJywndCcsJ2UnLCdtJywwfTsKICAgIHN0YXRpYyBjb25zdCBXQ0hBUiB3aW45eF9yZWdfcGF0aFdbXSA9IHsnXFwnLCdzJywneScsJ3MnLCd0JywnZScsJ20nLCcuJywnZCcsJ2EnLCd0JywwfTsKCiAgICBHZXRXaW5kb3dzRGlyZWN0b3J5Vyh3aW5kaXIsIE1BWF9QQVRITkFNRV9MRU4pOwoKICAgIC8qIHRlc3QgJXdpbmRpciUvc3lzdGVtMzIvY29uZmlnL3N5c3RlbSAtLT4gd2lubnQgKi8KICAgIHN0cmNweVcodG1wLCB3aW5kaXIpOwogICAgc3RyY2F0Vyh0bXAsIG50X3JlZ19wYXRoVyk7CiAgICBpZihHZXRGaWxlQXR0cmlidXRlc1codG1wKSAhPSAoRFdPUkQpLTEpCiAgICAgIHJldCA9IFJFR19XSU5OVDsKICAgIGVsc2UKICAgIHsKICAgICAgIC8qIHRlc3QgJXdpbmRpciUvc3lzdGVtLmRhdCAtLT4gd2luOTUgKi8KICAgICAgc3RyY3B5Vyh0bXAsIHdpbmRpcik7CiAgICAgIHN0cmNhdFcodG1wLCB3aW45eF9yZWdfcGF0aFcpOwogICAgICBpZihHZXRGaWxlQXR0cmlidXRlc1codG1wKSAhPSAoRFdPUkQpLTEpCiAgICAgICAgcmV0ID0gUkVHX1dJTjk1OwogICAgfQoKICAgIHJldHVybiByZXQ7Cn0KCiNkZWZpbmUgV0lORV9SRUdfVkVSX0VSUk9SICAtMQojZGVmaW5lIFdJTkVfUkVHX1ZFUl8xICAgICAgIDAKI2RlZmluZSBXSU5FX1JFR19WRVJfMiAgICAgICAxCiNkZWZpbmUgV0lORV9SRUdfVkVSX09MRCAgICAgMgojZGVmaW5lIFdJTkVfUkVHX1ZFUl9VTktOT1dOIDMKCi8qIHJldHVybiB0aGUgdmVyc2lvbiBvZiB3aW5lIHJlZ2lzdHJ5IGZpbGUgW0ludGVybmFsXSAqLwpzdGF0aWMgaW50IF9nZXRfd2luZV9yZWdpc3RyeV9maWxlX2Zvcm1hdF92ZXJzaW9uKExQQ1NUUiBmbikKewogICAgRklMRSAqZjsKICAgIGNoYXIgdG1wWzUwXTsKICAgIGludCB2ZXI7CgogICAgaWYgKChmPWZvcGVuKGZuLCJydCIpKSA9PSBOVUxMKSB7CiAgICAgICAgV0FSTigiQ291bGRuJ3Qgb3BlbiAlcyBmb3IgcmVhZGluZzogJXNcbiIsZm4sc3RyZXJyb3IoZXJybm8pKTsKICAgICAgICByZXR1cm4gV0lORV9SRUdfVkVSX0VSUk9SOwogICAgfQoKICAgIGlmIChmZ2V0cyh0bXAsNTAsZikgPT0gTlVMTCkgewogICAgICAgIFdBUk4oIkVycm9yIHJlYWRpbmcgJXM6ICVzXG4iLGZuLHN0cmVycm9yKGVycm5vKSk7CiAgICAgICAgZmNsb3NlKGYpOwogICAgICAgIHJldHVybiBXSU5FX1JFR19WRVJfRVJST1I7CiAgICB9CiAgICBmY2xvc2UoZik7CgogICAgaWYgKHNzY2FuZih0bXAsIldJTkUgUkVHSVNUUlkgVmVyc2lvbiAlZCIsJnZlcikgIT0gMSkgcmV0dXJuIFdJTkVfUkVHX1ZFUl9VTktOT1dOOwogICAgc3dpdGNoICh2ZXIpIHsKICAgICAgICBjYXNlIDE6CiAgICAgICAgICAgIHJldHVybiBXSU5FX1JFR19WRVJfMTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSAyOgogICAgICAgICAgICByZXR1cm4gV0lORV9SRUdfVkVSXzI7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgIHJldHVybiBXSU5FX1JFR19WRVJfVU5LTk9XTjsKICAgIH0KfQoKLyogbG9hZCB0aGUgcmVnaXN0cnkgZmlsZSBpbiB3aW5lIGZvcm1hdCBbSW50ZXJuYWxdICovCnN0YXRpYyB2b2lkIGxvYWRfd2luZV9yZWdpc3RyeShIS0VZIGhrZXksTFBDU1RSIGZuKQp7CiAgICBpbnQgZmlsZV9mb3JtYXQ7CgogICAgZmlsZV9mb3JtYXQgPSBfZ2V0X3dpbmVfcmVnaXN0cnlfZmlsZV9mb3JtYXRfdmVyc2lvbihmbik7CiAgICBzd2l0Y2ggKGZpbGVfZm9ybWF0KSB7CgogICAgICAgIGNhc2UgV0lORV9SRUdfVkVSXzE6CiAgICAgICAgICAgIFdBUk4oIlVuYWJsZSB0byBsb2FkIHJlZ2lzdHJ5IGZpbGUgJXM6IG9sZCBmb3JtYXQgd2hpY2ggaXMgbm8gbG9uZ2VyIHN1cHBvcnRlZC5cbiIsZm4pOwogICAgICAgICAgICBicmVhazsKCiAgICAgICAgY2FzZSBXSU5FX1JFR19WRVJfMjogewogICAgICAgICAgICBIQU5ETEUgZmlsZTsKICAgICAgICAgICAgaWYgKChmaWxlID0gRklMRV9DcmVhdGVGaWxlKCBmbiwgR0VORVJJQ19SRUFELCAwLCBOVUxMLCBPUEVOX0VYSVNUSU5HLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRklMRV9BVFRSSUJVVEVfTk9STUFMLCAwLCBUUlVFLCBEUklWRV9VTktOT1dOICkpKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBTRVJWRVJfU1RBUlRfUkVRKCBsb2FkX3JlZ2lzdHJ5ICkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICByZXEtPmhrZXkgICAgPSBoa2V5OwogICAgICAgICAgICAgICAgICAgIHJlcS0+ZmlsZSAgICA9IGZpbGU7CiAgICAgICAgICAgICAgICAgICAgd2luZV9zZXJ2ZXJfY2FsbCggcmVxICk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBTRVJWRVJfRU5EX1JFUTsKICAgICAgICAgICAgICAgIENsb3NlSGFuZGxlKCBmaWxlICk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgfQoKICAgICAgICBjYXNlIFdJTkVfUkVHX1ZFUl9VTktOT1dOOgogICAgICAgICAgICBXQVJOKCJVbmFibGUgdG8gbG9hZCByZWdpc3RyeSBmaWxlICVzOiB1bmtub3duIGZvcm1hdC5cbiIsZm4pOwogICAgICAgICAgICBicmVhazsKCiAgICAgICAgY2FzZSBXSU5FX1JFR19WRVJfRVJST1I6CiAgICAgICAgICAgIGJyZWFrOwogICAgfQp9CgovKiBnZW5lcmF0ZSBhbmQgcmV0dXJuIHRoZSBuYW1lIG9mIHRoZSB0bXAgZmlsZSBhbmQgYXNzb2NpYXRlZCBzdHJlYW0gW0ludGVybmFsXSAqLwpzdGF0aWMgTFBTVFIgX2dldF90bXBfZm4oRklMRSAqKmYpCnsKICAgIExQU1RSIHJldDsKICAgIGludCB0bXBfZmQsY291bnQ7CgogICAgcmV0ID0gX3htYWxsb2MoNTApOwogICAgZm9yIChjb3VudCA9IDA7OykgewogICAgICAgIHNwcmludGYocmV0LCIvdG1wL3JlZyVseCUwNHgudG1wIiwobG9uZylnZXRwaWQoKSxjb3VudCsrKTsKICAgICAgICBpZiAoKHRtcF9mZCA9IG9wZW4ocmV0LE9fQ1JFQVQgfCBPX0VYQ0wgfCBPX1dST05MWSwwNjY2KSkgIT0gLTEpIGJyZWFrOwogICAgICAgIGlmIChlcnJubyAhPSBFRVhJU1QpIHsKICAgICAgICAgICAgRVJSKCJVbmV4cGVjdGVkIGVycm9yIHdoaWxlIG9wZW4oKSBjYWxsOiAlc1xuIixzdHJlcnJvcihlcnJubykpOwogICAgICAgICAgICBmcmVlKHJldCk7CiAgICAgICAgICAgICpmID0gTlVMTDsKICAgICAgICAgICAgcmV0dXJuIE5VTEw7CiAgICAgICAgfQogICAgfQoKICAgIGlmICgoKmYgPSBmZG9wZW4odG1wX2ZkLCJ3IikpID09IE5VTEwpIHsKICAgICAgICBFUlIoIlVuZXhwZWN0ZWQgZXJyb3Igd2hpbGUgZmRvcGVuKCkgY2FsbDogJXNcbiIsc3RyZXJyb3IoZXJybm8pKTsKICAgICAgICBjbG9zZSh0bXBfZmQpOwogICAgICAgIGZyZWUocmV0KTsKICAgICAgICByZXR1cm4gTlVMTDsKICAgIH0KCiAgICByZXR1cm4gcmV0Owp9CgovKiBjb252ZXJ0IHdpbjk1IG5hdGl2ZSByZWdpc3RyeSBmaWxlIHRvIHdpbmUgZm9ybWF0IFtJbnRlcm5hbF0gKi8Kc3RhdGljIExQU1RSIF9jb252ZXJ0X3dpbjk1X3JlZ2lzdHJ5X3RvX3dpbmVfZm9ybWF0KExQQ1dTVFIgZm4sIGludCBsZXZlbCkKewogICAgaW50IGZkOwogICAgRklMRSAqZjsKICAgIERPU19GVUxMX05BTUUgZnVsbF9uYW1lOwogICAgdm9pZCAqYmFzZTsKICAgIExQU1RSIHJldCA9IE5VTEw7CiAgICBzdHJ1Y3Qgc3RhdCBzdDsKCiAgICBfdzk1Y3JlZyAqY3JlZzsKICAgIF93OTVyZ2tuICpyZ2tuOwogICAgX3c5NWRrZSAqZGtlLCAqcm9vdF9ka2U7CgogICAgaWYgKCFET1NGU19HZXRGdWxsTmFtZSggZm4sIDAsICZmdWxsX25hbWUgKSkgcmV0dXJuIE5VTEw7CgogICAgLyogbWFwIHRoZSByZWdpc3RyeSBpbnRvIHRoZSBtZW1vcnkgKi8KICAgIGlmICgoZmQgPSBvcGVuKGZ1bGxfbmFtZS5sb25nX25hbWUsIE9fUkRPTkxZIHwgT19OT05CTE9DSykpID09IC0xKSByZXR1cm4gTlVMTDsKICAgIGlmICgoZnN0YXQoZmQsICZzdCkgPT0gLTEpKSBnb3RvIGVycm9yMTsKICAgIGlmICghc3Quc3Rfc2l6ZSkgZ290byBlcnJvcjE7CiAgICBpZiAoKGJhc2UgPSBtbWFwKE5VTEwsIHN0LnN0X3NpemUsIFBST1RfUkVBRCwgTUFQX1BSSVZBVEUsIGZkLCAwKSkgPT0gTUFQX0ZBSUxFRCkgZ290byBlcnJvcjE7CgogICAgLyogY29udHJvbCBzaWduYXR1cmUgKi8KICAgIGlmICgqKExQRFdPUkQpYmFzZSAhPSBXOTVfUkVHX0NSRUdfSUQpIHsKICAgICAgICBFUlIoInVuYWJsZSB0byBsb2FkIG5hdGl2ZSB3aW45NSByZWdpc3RyeSBmaWxlICVzOiB1bmtub3duIHNpZ25hdHVyZS5cbiIsCiAgICAgICAgICAgIGRlYnVnc3RyX3coZm4pKTsKICAgICAgICBnb3RvIGVycm9yOwogICAgfQoKICAgIGNyZWcgPSBiYXNlOwogICAgLyogbG9hZCB0aGUgaGVhZGVyIChyZ2tuKSAqLwogICAgcmdrbiA9IChfdzk1cmdrbiopKGNyZWcgKyAxKTsKICAgIGlmIChyZ2tuLT5pZCAhPSBXOTVfUkVHX1JHS05fSUQpIHsKICAgICAgICBFUlIoInNlY29uZCBJRkYgaGVhZGVyIG5vdCBSR0tOLCBidXQgJWx4XG4iLCByZ2tuLT5pZCk7CiAgICAgICAgZ290byBlcnJvcjsKICAgIH0KICAgIGlmIChyZ2tuLT5yb290X29mZiAhPSAweDIwKSB7CiAgICAgICAgRVJSKCJyZ2tuLT5yb290X29mZiBub3QgMHgyMCwgcGxlYXNlIHJlcG9ydCAhXG4iKTsKICAgICAgICBnb3RvIGVycm9yOwogICAgfQogICAgaWYgKHJna24tPmxhc3RfZGtlID4gcmdrbi0+c2l6ZSkKICAgIHsKICAgICAgRVJSKCJyZWdpc3RyeSBmaWxlIGNvcnJ1cHQhIGxhc3RfZGtlID4gc2l6ZSFcbiIpOwogICAgICBnb3RvIGVycm9yOwogICAgfQogICAgLyogdmVyaWZ5IGxhc3QgZGtlICovCiAgICBka2UgPSAoX3c5NWRrZSopKChjaGFyKilyZ2tuICsgcmdrbi0+bGFzdF9ka2UpOwogICAgaWYgKGRrZS0+eDEgIT0gMHg4MDAwMDAwMCkKICAgIHsgLyogd3JvbmcgbWFnaWMgKi8KICAgICAgRVJSKCJsYXN0IGRrZSBpbnZhbGlkICFcbiIpOwogICAgICBnb3RvIGVycm9yOwogICAgfQogICAgaWYgKHJna24tPnNpemUgPiBjcmVnLT5yZ2RiX29mZikKICAgIHsKICAgICAgRVJSKCJyZWdpc3RyeSBmaWxlIGNvcnJ1cHQhIHJna24gc2l6ZSA+IHJnZGJfb2ZmICFcbiIpOwogICAgICBnb3RvIGVycm9yOwogICAgfQogICAgcm9vdF9ka2UgPSAoX3c5NWRrZSopKChjaGFyKilyZ2tuICsgcmdrbi0+cm9vdF9vZmYpOwogICAgaWYgKCAocm9vdF9ka2UtPnByZXZsdmwgIT0gMHhmZmZmZmZmZikgfHwgKHJvb3RfZGtlLT5uZXh0ICE9IDB4ZmZmZmZmZmYpICkKICAgIHsKICAgICAgICBFUlIoInJlZ2lzdHJ5IGZpbGUgY29ycnVwdCEgaW52YWxpZCByb290IGRrZSAhXG4iKTsKICAgICAgICBnb3RvIGVycm9yOwogICAgfQoKICAgIGlmICggKHJldCA9IF9nZXRfdG1wX2ZuKCZmKSkgPT0gTlVMTCkgZ290byBlcnJvcjsKICAgIGZwcmludGYoZiwiV0lORSBSRUdJU1RSWSBWZXJzaW9uIDIiKTsKICAgIF93OTVfZHVtcF9ka2UoIiIsY3JlZyxyZ2tuLHJvb3RfZGtlLGYsbGV2ZWwpOwogICAgZmNsb3NlKGYpOwoKZXJyb3I6CiAgICBpZihyZXQgPT0gTlVMTCkgewogICAgICAgIEVSUigiVW5hYmxlIHRvIGxvYWQgbmF0aXZlIHdpbjk1IHJlZ2lzdHJ5IGZpbGUgJXMuXG4iLCBkZWJ1Z3N0cl93KGZuKSk7CiAgICAgICAgRVJSKCJQbGVhc2UgcmVwb3J0IHRoaXMuXG4iKTsKICAgICAgICBFUlIoIk1ha2UgYSBiYWNrdXAgb2YgdGhlIGZpbGUsIHJ1biBhIGdvb2QgcmVnIGNsZWFuZXIgcHJvZ3JhbSBhbmQgdHJ5IGFnYWluIVxuIik7CiAgICB9CgogICAgbXVubWFwKGJhc2UsIHN0LnN0X3NpemUpOwplcnJvcjE6CiAgICBjbG9zZShmZCk7CiAgICByZXR1cm4gcmV0Owp9CgovKiBjb252ZXJ0IHdpbm50IG5hdGl2ZSByZWdpc3RyeSBmaWxlIHRvIHdpbmUgZm9ybWF0IFtJbnRlcm5hbF0gKi8Kc3RhdGljIExQU1RSIF9jb252ZXJ0X3dpbm50X3JlZ2lzdHJ5X3RvX3dpbmVfZm9ybWF0KExQQ1dTVFIgZm4sIGludCBsZXZlbCkKewogICAgRklMRSAqZjsKICAgIHZvaWQgKmJhc2U7CiAgICBMUFNUUiByZXQgPSBOVUxMOwogICAgSEFORExFIGhGaWxlOwogICAgSEFORExFIGhNYXBwaW5nOwoKICAgIG50X3JlZ2YgKnJlZ2Y7CiAgICBudF9oYmluICpoYmluOwogICAgbnRfaGJpbl9zdWIgKmhiaW5fc3ViOwogICAgbnRfbmsgKm5rOwoKICAgIFRSQUNFKCIlc1xuIiwgZGVidWdzdHJfdyhmbikpOwoKICAgIGhGaWxlID0gQ3JlYXRlRmlsZVcoIGZuLCBHRU5FUklDX1JFQUQsIEZJTEVfU0hBUkVfUkVBRCwgTlVMTCwgT1BFTl9FWElTVElORywgMCwgMCApOwogICAgaWYgKCBoRmlsZSA9PSBJTlZBTElEX0hBTkRMRV9WQUxVRSApIHJldHVybiBOVUxMOwogICAgaE1hcHBpbmcgPSBDcmVhdGVGaWxlTWFwcGluZ1coIGhGaWxlLCBOVUxMLCBQQUdFX1JFQURPTkxZfFNFQ19DT01NSVQsIDAsIDAsIE5VTEwgKTsKICAgIGlmICghaE1hcHBpbmcpIGdvdG8gZXJyb3IxOwogICAgYmFzZSA9IE1hcFZpZXdPZkZpbGUoIGhNYXBwaW5nLCBGSUxFX01BUF9SRUFELCAwLCAwLCAwICk7CiAgICBDbG9zZUhhbmRsZSggaE1hcHBpbmcgKTsKICAgIGlmICghYmFzZSkgZ290byBlcnJvcjE7CgogICAgLyogY29udHJvbCBzaWduYXR1cmUgKi8KICAgIGlmICgqKExQRFdPUkQpYmFzZSAhPSBOVF9SRUdfSEVBREVSX0JMT0NLX0lEKSB7CiAgICAgICAgRVJSKCJ1bmFibGUgdG8gbG9hZCBuYXRpdmUgd2lubnQgcmVnaXN0cnkgZmlsZSAlczogdW5rbm93biBzaWduYXR1cmUuXG4iLAogICAgICAgICAgICBkZWJ1Z3N0cl93KGZuKSk7CiAgICAgICAgZ290byBlcnJvcjsKICAgIH0KCiAgICAvKiBzdGFydCBibG9jayAqLwogICAgcmVnZiA9IGJhc2U7CgogICAgLyogaGJpbiBibG9jayAqLwogICAgaGJpbiA9IChudF9oYmluKikoKGNoYXIqKSBiYXNlICsgMHgxMDAwKTsKICAgIGlmIChoYmluLT5pZCAhPSBOVF9SRUdfUE9PTF9CTE9DS19JRCkgewogICAgICBFUlIoICJoYmluIGJsb2NrIGludmFsaWRcbiIpOwogICAgICBnb3RvIGVycm9yOwogICAgfQoKICAgIC8qIGhiaW5fc3ViIGJsb2NrICovCiAgICBoYmluX3N1YiA9IChudF9oYmluX3N1YiopJihoYmluLT5oYmluX3N1Yik7CiAgICBpZiAoKGhiaW5fc3ViLT5kYXRhWzBdICE9ICduJykgfHwgKGhiaW5fc3ViLT5kYXRhWzFdICE9ICdrJykpIHsKICAgICAgRVJSKCAiaGJpbl9zdWIgYmxvY2sgaW52YWxpZFxuIik7CiAgICAgIGdvdG8gZXJyb3I7CiAgICB9CgogICAgLyogbmsgYmxvY2sgKi8KICAgIG5rID0gKG50X25rKikmKGhiaW5fc3ViLT5kYXRhWzBdKTsKICAgIGlmIChuay0+VHlwZSAhPSBOVF9SRUdfUk9PVF9LRVlfQkxPQ0tfVFlQRSkgewogICAgICBFUlIoICJzcGVjaWFsIG5rIGJsb2NrIG5vdCBmb3VuZFxuIik7CiAgICAgIGdvdG8gZXJyb3I7CiAgICB9CgogICAgaWYgKCAocmV0ID0gX2dldF90bXBfZm4oJmYpKSA9PSBOVUxMKSBnb3RvIGVycm9yOwogICAgZnByaW50ZihmLCJXSU5FIFJFR0lTVFJZIFZlcnNpb24gMiIpOwogICAgX250X2R1bXBfbmsoIiIsKGNoYXIqKWJhc2UrMHgxMDAwLG5rLGYsbGV2ZWwpOwogICAgZmNsb3NlKGYpOwoKZXJyb3I6CiAgICBVbm1hcFZpZXdPZkZpbGUoIGJhc2UgKTsKZXJyb3IxOgogICAgQ2xvc2VIYW5kbGUoaEZpbGUpOwogICAgcmV0dXJuIHJldDsKfQoKLyogY29udmVydCBuYXRpdmUgcmVnaXN0cnkgdG8gd2luZSBmb3JtYXQgYW5kIGxvYWQgaXQgdmlhIHNlcnZlciBjYWxsIFtJbnRlcm5hbF0gKi8Kc3RhdGljIHZvaWQgX2NvbnZlcnRfYW5kX2xvYWRfbmF0aXZlX3JlZ2lzdHJ5KExQQ1dTVFIgZm4sIEhLRVkgaGtleSwgaW50IHJlZ190eXBlLCBpbnQgbGV2ZWwpCnsKICAgIExQU1RSIHRtcCA9IE5VTEw7CgogICAgc3dpdGNoIChyZWdfdHlwZSkgewogICAgICAgIGNhc2UgUkVHX1dJTk5UOgogICAgICAgICAgICAvKiBGSVhNRTogZm9sbG93aW5nIGZ1bmN0aW9uIGRvZXNuJ3QgcmVhbGx5IGNvbnZlcnQgeWV0ICovCiAgICAgICAgICAgIHRtcCA9IF9jb252ZXJ0X3dpbm50X3JlZ2lzdHJ5X3RvX3dpbmVfZm9ybWF0KGZuLGxldmVsKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSBSRUdfV0lOOTU6CiAgICAgICAgICAgIHRtcCA9IF9jb252ZXJ0X3dpbjk1X3JlZ2lzdHJ5X3RvX3dpbmVfZm9ybWF0KGZuLGxldmVsKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSBSRUdfV0lOMzE6CiAgICAgICAgICAgIEVSUigiRG9uJ3Qga25vdyBob3cgdG8gY29udmVydCBuYXRpdmUgMy4xIHJlZ2lzdHJ5IHlldC5cbiIpOwogICAgICAgICAgICBicmVhazsKICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICBFUlIoIlVua25vd24gcmVnaXN0cnkgZm9ybWF0IHBhcmFtZXRlciAoJWQpXG4iLHJlZ190eXBlKTsKICAgICAgICAgICAgYnJlYWs7CiAgICB9CgogICAgaWYgKHRtcCAhPSBOVUxMKSB7CiAgICAgICAgbG9hZF93aW5lX3JlZ2lzdHJ5KGhrZXksdG1wKTsKICAgICAgICBUUkFDRSgiRmlsZSAlcyBzdWNjZXNzZnVsbHkgY29udmVydGVkIHRvICVzIGFuZCBsb2FkZWQgdG8gcmVnaXN0cnkuXG4iLAogICAgICAgICAgICAgIGRlYnVnc3RyX3coZm4pLCB0bXApOwogICAgICAgIHVubGluayh0bXApOwogICAgfQogICAgZWxzZSBXQVJOKCJVbmFibGUgdG8gY29udmVydCAlcyAoZG9lc24ndCBleGlzdD8pXG4iLCBkZWJ1Z3N0cl93KGZuKSk7CiAgICBmcmVlKHRtcCk7Cn0KCi8qIGxvYWQgYWxsIG5hdGl2ZSB3aW5kb3dzIHJlZ2lzdHJ5IGZpbGVzIFtJbnRlcm5hbF0gKi8Kc3RhdGljIHZvaWQgX2xvYWRfd2luZG93c19yZWdpc3RyeSggSEtFWSBoa2V5X2xvY2FsX21hY2hpbmUsIEhLRVkgaGtleV9jdXJyZW50X3VzZXIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEhLRVkgaGtleV91c2Vyc19kZWZhdWx0ICkKewogICAgaW50IHJlZ190eXBlOwogICAgV0NIQVIgd2luZGlyW01BWF9QQVRITkFNRV9MRU5dOwogICAgV0NIQVIgcGF0aFtNQVhfUEFUSE5BTUVfTEVOXTsKICAgIE9CSkVDVF9BVFRSSUJVVEVTIGF0dHI7CiAgICBVTklDT0RFX1NUUklORyBuYW1lVzsKICAgIEhLRVkgaGtleTsKCiAgICBzdGF0aWMgY29uc3QgV0NIQVIgV2luZVdbXSA9IHsnVycsJ2knLCduJywnZScsMH07CiAgICBzdGF0aWMgY29uc3QgV0NIQVIgUHJvZmlsZVdbXSA9IHsnUCcsJ3InLCdvJywnZicsJ2knLCdsJywnZScsMH07CiAgICBzdGF0aWMgY29uc3QgV0NIQVIgZW1wdHlfc3RyV1tdID0geyAwIH07CiAgICBzdGF0aWMgY29uc3QgV0NIQVIgU3lzdGVtW10gPSB7J00nLCdhJywnYycsJ2gnLCdpJywnbicsJ2UnLCdcXCcsJ1MnLCd5JywncycsJ3QnLCdlJywnbScsMH07CiAgICBzdGF0aWMgY29uc3QgV0NIQVIgU29mdHdhcmVbXSA9IHsnTScsJ2EnLCdjJywnaCcsJ2knLCduJywnZScsJ1xcJywnUycsJ28nLCdmJywndCcsJ3cnLCdhJywncicsJ2UnLDB9OwogICAgc3RhdGljIGNvbnN0IFdDSEFSIENsb25lW10gPSB7J00nLCdhJywnYycsJ2gnLCdpJywnbicsJ2UnLCdcXCcsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnUycsJ3knLCdzJywndCcsJ2UnLCdtJywnXFwnLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ0MnLCdsJywnbycsJ24nLCdlJywwfTsKCiAgICBhdHRyLkxlbmd0aCA9IHNpemVvZihhdHRyKTsKICAgIGF0dHIuUm9vdERpcmVjdG9yeSA9IDA7CiAgICBhdHRyLk9iamVjdE5hbWUgPSAmbmFtZVc7CiAgICBhdHRyLkF0dHJpYnV0ZXMgPSAwOwogICAgYXR0ci5TZWN1cml0eURlc2NyaXB0b3IgPSBOVUxMOwogICAgYXR0ci5TZWN1cml0eVF1YWxpdHlPZlNlcnZpY2UgPSBOVUxMOwoKICAgIEdldFdpbmRvd3NEaXJlY3RvcnlXKHdpbmRpciwgTUFYX1BBVEhOQU1FX0xFTik7CgogICAgcmVnX3R5cGUgPSBfZ2V0X3JlZ190eXBlKCk7CiAgICBzd2l0Y2ggKHJlZ190eXBlKSB7CiAgICAgICAgY2FzZSBSRUdfV0lOTlQ6IHsKICAgICAgICAgICAgSEtFWSBoa2V5OwogICAgICAgICAgICBzdGF0aWMgY29uc3QgV0NIQVIgbnR1c2VyX2RhdFdbXSA9IHsnXFwnLCduJywndCcsJ3UnLCdzJywnZScsJ3InLCcuJywnZCcsJ2EnLCd0JywwfTsKICAgICAgICAgICAgc3RhdGljIGNvbnN0IFdDSEFSIGRlZmF1bHRXW10gPSB7J1xcJywncycsJ3knLCdzJywndCcsJ2UnLCdtJywnMycsJzInLCdcXCcsJ2MnLCdvJywnbicsJ2YnLCdpJywnZycsJ1xcJywnZCcsJ2UnLCdmJywnYScsJ3UnLCdsJywndCcsMH07CiAgICAgICAgICAgIHN0YXRpYyBjb25zdCBXQ0hBUiBzeXN0ZW1XW10gPSB7J1xcJywncycsJ3knLCdzJywndCcsJ2UnLCdtJywnMycsJzInLCdcXCcsJ2MnLCdvJywnbicsJ2YnLCdpJywnZycsJ1xcJywncycsJ3knLCdzJywndCcsJ2UnLCdtJywwfTsKICAgICAgICAgICAgc3RhdGljIGNvbnN0IFdDSEFSIHNvZnR3YXJlV1tdID0geydcXCcsJ3MnLCd5JywncycsJ3QnLCdlJywnbScsJzMnLCcyJywnXFwnLCdjJywnbycsJ24nLCdmJywnaScsJ2cnLCdcXCcsJ3MnLCdvJywnZicsJ3QnLCd3JywnYScsJ3InLCdlJywwfTsKICAgICAgICAgICAgc3RhdGljIGNvbnN0IFdDSEFSIHNhbVdbXSA9IHsnXFwnLCdzJywneScsJ3MnLCd0JywnZScsJ20nLCczJywnMicsJ1xcJywnYycsJ28nLCduJywnZicsJ2knLCdnJywnXFwnLCdzJywnYScsJ20nLDB9OwogICAgICAgICAgICBzdGF0aWMgY29uc3QgV0NIQVIgc2VjdXJpdHlXW10gPSB7J1xcJywncycsJ3knLCdzJywndCcsJ2UnLCdtJywnMycsJzInLCdcXCcsJ2MnLCdvJywnbicsJ2YnLCdpJywnZycsJ1xcJywncycsJ2UnLCdjJywndScsJ3InLCdpJywndCcsJ3knLDB9OwoKICAgICAgICAgICAgLyogdXNlciBzcGVjaWZpYyBudHVzZXIuZGF0ICovCiAgICAgICAgICAgIGlmIChQUk9GSUxFX0dldFdpbmVJbmlTdHJpbmcoIFdpbmVXLCBQcm9maWxlVywgZW1wdHlfc3RyVywgcGF0aCwgTUFYX1BBVEhOQU1FX0xFTiApKSB7CiAgICAgICAgICAgICAgICBzdHJjYXRXKHBhdGgsIG50dXNlcl9kYXRXKTsKICAgICAgICAgICAgICAgIF9jb252ZXJ0X2FuZF9sb2FkX25hdGl2ZV9yZWdpc3RyeShwYXRoLGhrZXlfY3VycmVudF91c2VyLFJFR19XSU5OVCwxKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIE1FU1NBR0UoIldoZW4geW91IGFyZSBydW5uaW5nIHdpdGggYSBuYXRpdmUgTlQgZGlyZWN0b3J5IHNwZWNpZnlcbiIpOwogICAgICAgICAgICAgICAgTUVTU0FHRSgiJ1Byb2ZpbGU9PHByb2ZpbGVkaXJlY3Rvcnk+JyBvciBkaXNhYmxlIGxvYWRpbmcgb2YgV2luZG93c1xuIik7CiAgICAgICAgICAgICAgICBNRVNTQUdFKCJyZWdpc3RyeSAoTG9hZFdpbmRvd3NSZWdpc3RyeUZpbGVzPU4pXG4iKTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9CgogICAgICAgICAgICAvKiBkZWZhdWx0IHVzZXIuZGF0ICovCiAgICAgICAgICAgIGlmIChoa2V5X3VzZXJzX2RlZmF1bHQpIHsKICAgICAgICAgICAgICAgIHN0cmNweVcocGF0aCwgd2luZGlyKTsKICAgICAgICAgICAgICAgIHN0cmNhdFcocGF0aCwgZGVmYXVsdFcpOwogICAgICAgICAgICAgICAgX2NvbnZlcnRfYW5kX2xvYWRfbmF0aXZlX3JlZ2lzdHJ5KHBhdGgsaGtleV91c2Vyc19kZWZhdWx0LFJFR19XSU5OVCwxKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgLyoKICAgICAgICAgICAgKiBGSVhNRQogICAgICAgICAgICAqICBtYXAgSExNXFN5c3RlbVxDb250cm9sU2V0MDAxIHRvIEhMTVxTeXN0ZW1cQ3VycmVudENvbnRyb2xTZXQKICAgICAgICAgICAgKi8KICAgICAgICAgICAgUnRsSW5pdFVuaWNvZGVTdHJpbmcoICZuYW1lVywgU3lzdGVtICk7CiAgICAgICAgICAgIGlmICghTnRDcmVhdGVLZXkoICZoa2V5LCBLRVlfQUxMX0FDQ0VTUywgJmF0dHIsIDAsIE5VTEwsIDAsIE5VTEwgKSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgc3RyY3B5VyhwYXRoLCB3aW5kaXIpOwogICAgICAgICAgICAgICAgc3RyY2F0VyhwYXRoLCBzeXN0ZW1XKTsKICAgICAgICAgICAgICAgIF9jb252ZXJ0X2FuZF9sb2FkX25hdGl2ZV9yZWdpc3RyeShwYXRoLGhrZXksUkVHX1dJTk5ULDEpOwogICAgICAgICAgICAgICAgTnRDbG9zZSggaGtleSApOwogICAgICAgICAgICB9CiAgICAgICAgICAgIFJ0bEluaXRVbmljb2RlU3RyaW5nKCAmbmFtZVcsIFNvZnR3YXJlICk7CiAgICAgICAgICAgIGlmICghTnRDcmVhdGVLZXkoICZoa2V5LCBLRVlfQUxMX0FDQ0VTUywgJmF0dHIsIDAsIE5VTEwsIDAsIE5VTEwgKSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgc3RyY3B5VyhwYXRoLCB3aW5kaXIpOwogICAgICAgICAgICAgICAgc3RyY2F0VyhwYXRoLCBzb2Z0d2FyZVcpOwogICAgICAgICAgICAgICAgX2NvbnZlcnRfYW5kX2xvYWRfbmF0aXZlX3JlZ2lzdHJ5KHBhdGgsaGtleSxSRUdfV0lOTlQsMSk7CiAgICAgICAgICAgICAgICBOdENsb3NlKCBoa2V5ICk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHN0cmNweVcocGF0aCwgd2luZGlyKTsKICAgICAgICAgICAgc3RyY2F0VyhwYXRoLCBzYW1XKTsKICAgICAgICAgICAgX2NvbnZlcnRfYW5kX2xvYWRfbmF0aXZlX3JlZ2lzdHJ5KHBhdGgsaGtleV9sb2NhbF9tYWNoaW5lLFJFR19XSU5OVCwwKTsKCiAgICAgICAgICAgIHN0cmNweVcocGF0aCx3aW5kaXIpOwogICAgICAgICAgICBzdHJjYXRXKHBhdGgsIHNlY3VyaXR5Vyk7CiAgICAgICAgICAgIF9jb252ZXJ0X2FuZF9sb2FkX25hdGl2ZV9yZWdpc3RyeShwYXRoLGhrZXlfbG9jYWxfbWFjaGluZSxSRUdfV0lOTlQsMCk7CgogICAgICAgICAgICAvKiB0aGlzIGtleSBpcyBnZW5lcmF0ZWQgd2hlbiB0aGUgbnQtY29yZSBib290ZWQgc3VjY2Vzc2Z1bGx5ICovCiAgICAgICAgICAgIFJ0bEluaXRVbmljb2RlU3RyaW5nKCAmbmFtZVcsIENsb25lICk7CiAgICAgICAgICAgIGlmICghTnRDcmVhdGVLZXkoICZoa2V5LCBLRVlfQUxMX0FDQ0VTUywgJmF0dHIsIDAsIE5VTEwsIDAsIE5VTEwgKSkgTnRDbG9zZSggaGtleSApOwogICAgICAgICAgICBicmVhazsKICAgICAgICB9CgogICAgICAgIGNhc2UgUkVHX1dJTjk1OgogICAgICAgIHsKICAgICAgICAgICAgc3RhdGljIGNvbnN0IFdDSEFSIHN5c3RlbV8xc3RXW10gPSB7J2MnLCc6JywnXFwnLCdzJywneScsJ3MnLCd0JywnZScsJ20nLCcuJywnMScsJ3MnLCd0JywwfTsKICAgICAgICAgICAgc3RhdGljIGNvbnN0IFdDSEFSIHN5c3RlbV9kYXRXW10gPSB7J1xcJywncycsJ3knLCdzJywndCcsJ2UnLCdtJywnLicsJ2QnLCdhJywndCcsMH07CiAgICAgICAgICAgIHN0YXRpYyBjb25zdCBXQ0hBUiBjbGFzc2VzX2RhdFdbXSA9IHsnXFwnLCdjJywnbCcsJ2EnLCdzJywncycsJ2UnLCdzJywnLicsJ2QnLCdhJywndCcsMH07CiAgICAgICAgICAgIHN0YXRpYyBjb25zdCBXQ0hBUiB1c2VyX2RhdFdbXSA9IHsnXFwnLCd1JywncycsJ2UnLCdyJywnLicsJ2QnLCdhJywndCcsMH07CgogICAgICAgICAgICBfY29udmVydF9hbmRfbG9hZF9uYXRpdmVfcmVnaXN0cnkoc3lzdGVtXzFzdFcsaGtleV9sb2NhbF9tYWNoaW5lLFJFR19XSU45NSwwKTsKCiAgICAgICAgICAgIHN0cmNweVcocGF0aCwgd2luZGlyKTsKICAgICAgICAgICAgc3RyY2F0VyhwYXRoLCBzeXN0ZW1fZGF0Vyk7CiAgICAgICAgICAgIF9jb252ZXJ0X2FuZF9sb2FkX25hdGl2ZV9yZWdpc3RyeShwYXRoLGhrZXlfbG9jYWxfbWFjaGluZSxSRUdfV0lOOTUsMCk7CgogICAgICAgICAgICBSdGxJbml0VW5pY29kZVN0cmluZyggJm5hbWVXLCBDbGFzc2VzUm9vdFcgKTsKICAgICAgICAgICAgaWYgKCFOdENyZWF0ZUtleSggJmhrZXksIEtFWV9BTExfQUNDRVNTLCAmYXR0ciwgMCwgTlVMTCwgMCwgTlVMTCApKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBzdHJjcHlXKHBhdGgsIHdpbmRpcik7CiAgICAgICAgICAgICAgICBzdHJjYXRXKHBhdGgsIGNsYXNzZXNfZGF0Vyk7CiAgICAgICAgICAgICAgICBfY29udmVydF9hbmRfbG9hZF9uYXRpdmVfcmVnaXN0cnkocGF0aCxoa2V5LFJFR19XSU45NSwwKTsKICAgICAgICAgICAgICAgIE50Q2xvc2UoIGhrZXkgKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKFBST0ZJTEVfR2V0V2luZUluaVN0cmluZyhXaW5lVywgUHJvZmlsZVcsIGVtcHR5X3N0clcsIHBhdGgsIE1BWF9QQVRITkFNRV9MRU4pKSB7CgkgICAgICAgIC8qIHVzZXIgc3BlY2lmaWMgdXNlci5kYXQgKi8KCSAgICAgICAgc3RyY2F0VyhwYXRoLCB1c2VyX2RhdFcpOwogICAgICAgICAgICAgICAgX2NvbnZlcnRfYW5kX2xvYWRfbmF0aXZlX3JlZ2lzdHJ5KHBhdGgsaGtleV9jdXJyZW50X3VzZXIsUkVHX1dJTjk1LDEpOwoKCSAgICAgICAgLyogZGVmYXVsdCB1c2VyLmRhdCAqLwoJICAgICAgICBpZiAoaGtleV91c2Vyc19kZWZhdWx0KSB7CiAgICAgICAgICAgICAgICAgICAgc3RyY3B5VyhwYXRoLCB3aW5kaXIpOwogICAgICAgICAgICAgICAgICAgIHN0cmNhdFcocGF0aCwgdXNlcl9kYXRXKTsKICAgICAgICAgICAgICAgICAgICBfY29udmVydF9hbmRfbG9hZF9uYXRpdmVfcmVnaXN0cnkocGF0aCxoa2V5X3VzZXJzX2RlZmF1bHQsUkVHX1dJTjk1LDEpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgc3RyY3B5VyhwYXRoLCB3aW5kaXIpOwogICAgICAgICAgICAgICAgc3RyY2F0VyhwYXRoLCB1c2VyX2RhdFcpOwogICAgICAgICAgICAgICAgX2NvbnZlcnRfYW5kX2xvYWRfbmF0aXZlX3JlZ2lzdHJ5KHBhdGgsaGtleV9jdXJyZW50X3VzZXIsUkVHX1dJTjk1LDEpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIH0KCiAgICAgICAgY2FzZSBSRUdfV0lOMzE6CiAgICAgICAgICAgIC8qIEZJWE1FOiBoZXJlIHdlIHNob3VsZCBjb252ZXJ0IHRvICoucmVnIGZpbGUgc3VwcG9ydGVkIGJ5IHNlcnZlciBhbmQgY2FsbCBSRVFfTE9BRF9SRUdJU1RSWSwgc2VlIFJFR19XSU45NSBjYXNlICovCiAgICAgICAgICAgIF93MzFfbG9hZHJlZygpOwogICAgICAgICAgICBicmVhazsKCiAgICAgICAgY2FzZSBSRUdfRE9OVExPQUQ6CiAgICAgICAgICAgIFRSQUNFKCJSRUdfRE9OVExPQURcbiIpOwogICAgICAgICAgICBicmVhazsKCiAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgRVJSKCJzd2l0Y2g6IG5vIG1hdGNoICglZClcbiIscmVnX3R5cGUpOwogICAgICAgICAgICBicmVhazsKCiAgICB9Cn0KCi8qIGxvYWQgaG9tZSByZWdpc3RyeSBmaWxlcyAoc3RvcmVkIGluIH4vLndpbmUpIFtJbnRlcm5hbF0gKi8Kc3RhdGljIHZvaWQgX2xvYWRfaG9tZV9yZWdpc3RyeSggSEtFWSBoa2V5X2xvY2FsX21hY2hpbmUsIEhLRVkgaGtleV9jdXJyZW50X3VzZXIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEhLRVkgaGtleV91c2Vyc19kZWZhdWx0ICkKewogICAgTFBDU1RSIGNvbmZkaXIgPSB3aW5lX2dldF9jb25maWdfZGlyKCk7CiAgICBMUFNUUiB0bXAgPSBfeG1hbGxvYyhzdHJsZW4oY29uZmRpcikrMjApOwoKICAgIHN0cmNweSh0bXAsY29uZmRpcik7CiAgICBzdHJjYXQodG1wLCIvIiBTQVZFX0xPQ0FMX1JFR0JSQU5DSF9VU0VSX0RFRkFVTFQpOwogICAgbG9hZF93aW5lX3JlZ2lzdHJ5KGhrZXlfdXNlcnNfZGVmYXVsdCx0bXApOwoKICAgIHN0cmNweSh0bXAsY29uZmRpcik7CiAgICBzdHJjYXQodG1wLCIvIiBTQVZFX0xPQ0FMX1JFR0JSQU5DSF9DVVJSRU5UX1VTRVIpOwogICAgbG9hZF93aW5lX3JlZ2lzdHJ5KGhrZXlfY3VycmVudF91c2VyLHRtcCk7CgogICAgc3RyY3B5KHRtcCxjb25mZGlyKTsKICAgIHN0cmNhdCh0bXAsIi8iIFNBVkVfTE9DQUxfUkVHQlJBTkNIX0xPQ0FMX01BQ0hJTkUpOwogICAgbG9hZF93aW5lX3JlZ2lzdHJ5KGhrZXlfbG9jYWxfbWFjaGluZSx0bXApOwoKICAgIGZyZWUodG1wKTsKfQoKCi8qIGxvYWQgYWxsIHJlZ2lzdHJ5IChuYXRpdmUgYW5kIGdsb2JhbCBhbmQgaG9tZSkgKi8Kdm9pZCBTSEVMTF9Mb2FkUmVnaXN0cnkoIHZvaWQgKQp7CiAgICBIS0VZIGhrZXlfbG9jYWxfbWFjaGluZSwgaGtleV91c2VycywgaGtleV91c2Vyc19kZWZhdWx0LCBoa2V5X2N1cnJlbnRfdXNlciwgaGtleV9jb25maWc7CiAgICBPQkpFQ1RfQVRUUklCVVRFUyBhdHRyOwogICAgVU5JQ09ERV9TVFJJTkcgbmFtZVc7CiAgICBEV09SRCBjb3VudDsKICAgIEJPT0wgcmVzOwogICAgaW50IGFsbCwgcGVyaW9kOwogICAgY2hhciB0bXBbMTAyNF07CgogICAgc3RhdGljIGNvbnN0IFdDSEFSIE1hY2hpbmVXW10gPSB7J00nLCdhJywnYycsJ2gnLCdpJywnbicsJ2UnLDB9OwogICAgc3RhdGljIGNvbnN0IFdDSEFSIFVzZXJXW10gPSB7J1UnLCdzJywnZScsJ3InLDB9OwogICAgc3RhdGljIGNvbnN0IFdDSEFSIERlZmF1bHRXW10gPSB7Jy4nLCdEJywnZScsJ2YnLCdhJywndScsJ2wnLCd0JywwfTsKICAgIHN0YXRpYyBjb25zdCBXQ0hBUiBSZWdpc3RyeVdbXSA9IHsnTScsJ2EnLCdjJywnaCcsJ2knLCduJywnZScsJ1xcJywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnUycsJ28nLCdmJywndCcsJ3cnLCdhJywncicsJ2UnLCdcXCcsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ1cnLCdpJywnbicsJ2UnLCdcXCcsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ1cnLCdpJywnbicsJ2UnLCdcXCcsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ0MnLCdvJywnbicsJ2YnLCdpJywnZycsJ1xcJywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnUicsJ2UnLCdnJywnaScsJ3MnLCd0JywncicsJ3knLDB9OwogICAgc3RhdGljIGNvbnN0IFdDSEFSIGxvYWRfd2luX3JlZ19maWxlc1dbXSA9IHsnTCcsJ28nLCdhJywnZCcsJ1cnLCdpJywnbicsJ2QnLCdvJywndycsJ3MnLCdSJywnZScsJ2cnLCdpJywncycsJ3QnLCdyJywneScsJ0YnLCdpJywnbCcsJ2UnLCdzJywwfTsKICAgIHN0YXRpYyBjb25zdCBXQ0hBUiBsb2FkX2dsb2JhbF9yZWdfZmlsZXNXW10gPSB7J0wnLCdvJywnYScsJ2QnLCdHJywnbCcsJ28nLCdiJywnYScsJ2wnLCdSJywnZScsJ2cnLCdpJywncycsJ3QnLCdyJywneScsJ0YnLCdpJywnbCcsJ2UnLCdzJywwfTsKICAgIHN0YXRpYyBjb25zdCBXQ0hBUiBsb2FkX2hvbWVfcmVnX2ZpbGVzV1tdID0geydMJywnbycsJ2EnLCdkJywnSCcsJ28nLCdtJywnZScsJ1InLCdlJywnZycsJ2knLCdzJywndCcsJ3InLCd5JywnRicsJ2knLCdsJywnZScsJ3MnLDB9OwogICAgc3RhdGljIGNvbnN0IFdDSEFSIFNhdmVPbmx5VXBkYXRlZEtleXNXW10gPSB7J1MnLCdhJywndicsJ2UnLCdPJywnbicsJ2wnLCd5JywnVScsJ3AnLCdkJywnYScsJ3QnLCdlJywnZCcsJ0snLCdlJywneScsJ3MnLDB9OwogICAgc3RhdGljIGNvbnN0IFdDSEFSIFBlcmlvZGljU2F2ZVdbXSA9IHsnUCcsJ2UnLCdyJywnaScsJ28nLCdkJywnaScsJ2MnLCdTJywnYScsJ3YnLCdlJywwfTsKICAgIHN0YXRpYyBjb25zdCBXQ0hBUiBXcml0ZXRvSG9tZVJlZ2lzdHJ5RmlsZXNXW10gPSB7J1cnLCdyJywnaScsJ3QnLCdlJywndCcsJ28nLCdIJywnbycsJ20nLCdlJywnUicsJ2UnLCdnJywnaScsJ3MnLCd0JywncicsJ3knLCdGJywnaScsJ2wnLCdlJywncycsMH07CiAgICBzdGF0aWMgY29uc3QgV0NIQVIgR2xvYmFsUmVnaXN0cnlEaXJXW10gPSB7J0cnLCdsJywnbycsJ2InLCdhJywnbCcsJ1InLCdlJywnZycsJ2knLCdzJywndCcsJ3InLCd5JywnRCcsJ2knLCdyJywwfTsKCiAgICBUUkFDRSgiKHZvaWQpXG4iKTsKCiAgICBpZiAoIUNMSUVOVF9Jc0Jvb3RUaHJlYWQoKSkgcmV0dXJuOyAgLyogYWxyZWFkeSBsb2FkZWQgKi8KCiAgICBhdHRyLkxlbmd0aCA9IHNpemVvZihhdHRyKTsKICAgIGF0dHIuUm9vdERpcmVjdG9yeSA9IDA7CiAgICBhdHRyLk9iamVjdE5hbWUgPSAmbmFtZVc7CiAgICBhdHRyLkF0dHJpYnV0ZXMgPSAwOwogICAgYXR0ci5TZWN1cml0eURlc2NyaXB0b3IgPSBOVUxMOwogICAgYXR0ci5TZWN1cml0eVF1YWxpdHlPZlNlcnZpY2UgPSBOVUxMOwoKICAgIFJ0bEluaXRVbmljb2RlU3RyaW5nKCAmbmFtZVcsIE1hY2hpbmVXICk7CiAgICBOdENyZWF0ZUtleSggJmhrZXlfbG9jYWxfbWFjaGluZSwgS0VZX0FMTF9BQ0NFU1MsICZhdHRyLCAwLCBOVUxMLCAwLCBOVUxMICk7CiAgICBSdGxJbml0VW5pY29kZVN0cmluZyggJm5hbWVXLCBVc2VyVyApOwogICAgTnRDcmVhdGVLZXkoICZoa2V5X3VzZXJzLCBLRVlfQUxMX0FDQ0VTUywgJmF0dHIsIDAsIE5VTEwsIDAsIE5VTEwgKTsKCiAgICBhdHRyLlJvb3REaXJlY3RvcnkgPSBoa2V5X3VzZXJzOwogICAgUnRsSW5pdFVuaWNvZGVTdHJpbmcoICZuYW1lVywgRGVmYXVsdFcgKTsKICAgIGlmIChOdENyZWF0ZUtleSggJmhrZXlfdXNlcnNfZGVmYXVsdCwgS0VZX0FMTF9BQ0NFU1MsICZhdHRyLCAwLCBOVUxMLCAwLCBOVUxMICkpCiAgICB7CiAgICAgICAgRVJSKCJDYW5ub3QgY3JlYXRlIEhLRVlfVVNFUlMvLkRlZmF1bHRcbiIgKTsKICAgICAgICBFeGl0UHJvY2VzcygxKTsKICAgIH0KICAgIFJ0bE9wZW5DdXJyZW50VXNlciggS0VZX0FMTF9BQ0NFU1MsICZoa2V5X2N1cnJlbnRfdXNlciApOwoKICAgIF9zZXRfcmVnaXN0cnlfbGV2ZWxzKDAsMCwwKTsKICAgIF9hbGxvY2F0ZV9kZWZhdWx0X2tleXMoKTsKCiAgICBhdHRyLlJvb3REaXJlY3RvcnkgPSAwOwogICAgUnRsSW5pdFVuaWNvZGVTdHJpbmcoICZuYW1lVywgUmVnaXN0cnlXICk7CiAgICBpZiAoTnRPcGVuS2V5KCAmaGtleV9jb25maWcsIEtFWV9BTExfQUNDRVNTLCAmYXR0ciApKSBoa2V5X2NvbmZpZyA9IDA7CgogICAgLyogbG9hZCB3aW5kb3dzIHJlZ2lzdHJ5IGlmIHJlcXVpcmVkICovCgogICAgcmVzID0gVFJVRTsKICAgIGF0dHIuUm9vdERpcmVjdG9yeSA9IGhrZXlfY29uZmlnOwogICAgUnRsSW5pdFVuaWNvZGVTdHJpbmcoICZuYW1lVywgbG9hZF93aW5fcmVnX2ZpbGVzVyApOwogICAgaWYgKCFOdFF1ZXJ5VmFsdWVLZXkoIGhrZXlfY29uZmlnLCAmbmFtZVcsIEtleVZhbHVlUGFydGlhbEluZm9ybWF0aW9uLCB0bXAsIHNpemVvZih0bXApLCAmY291bnQgKSkKICAgIHsKICAgICAgICBXQ0hBUiAqc3RyID0gKFdDSEFSICopKChLRVlfVkFMVUVfUEFSVElBTF9JTkZPUk1BVElPTiAqKXRtcCktPkRhdGE7CiAgICAgICAgcmVzID0gIUlTX09QVElPTl9GQUxTRShzdHJbMF0pOwogICAgfQogICAgaWYgKHJlcykgX2xvYWRfd2luZG93c19yZWdpc3RyeSggaGtleV9sb2NhbF9tYWNoaW5lLCBoa2V5X2N1cnJlbnRfdXNlciwgaGtleV91c2Vyc19kZWZhdWx0ICk7CgogICAgLyogbG9hZCBnbG9iYWwgcmVnaXN0cnkgaWYgcmVxdWlyZWQgKi8KCiAgICByZXMgPSBUUlVFOwogICAgUnRsSW5pdFVuaWNvZGVTdHJpbmcoICZuYW1lVywgbG9hZF9nbG9iYWxfcmVnX2ZpbGVzVyApOwogICAgaWYgKCFOdFF1ZXJ5VmFsdWVLZXkoIGhrZXlfY29uZmlnLCAmbmFtZVcsIEtleVZhbHVlUGFydGlhbEluZm9ybWF0aW9uLCB0bXAsIHNpemVvZih0bXApLCAmY291bnQgKSkKICAgIHsKICAgICAgICBXQ0hBUiAqc3RyID0gKFdDSEFSICopKChLRVlfVkFMVUVfUEFSVElBTF9JTkZPUk1BVElPTiAqKXRtcCktPkRhdGE7CiAgICAgICAgcmVzID0gIUlTX09QVElPTl9GQUxTRShzdHJbMF0pOwogICAgfQogICAgaWYgKHJlcykKICAgIHsKICAgICAgICAvKiBsb2FkIGdsb2JhbCByZWdpc3RyeSBmaWxlcyAoc3RvcmVkIGluIC9ldGMvd2luZSkgKi8KICAgICAgICBjaGFyICpwLCBjb25maWdmaWxlW01BWF9QQVRITkFNRV9MRU5dOwoKICAgICAgICAvKiBPdmVycmlkZSBFVENESVI/ICovCiAgICAgICAgY29uZmlnZmlsZVswXSA9IDA7CiAgICAgICAgUnRsSW5pdFVuaWNvZGVTdHJpbmcoICZuYW1lVywgR2xvYmFsUmVnaXN0cnlEaXJXICk7CiAgICAgICAgaWYgKCFOdFF1ZXJ5VmFsdWVLZXkoIGhrZXlfY29uZmlnLCAmbmFtZVcsIEtleVZhbHVlUGFydGlhbEluZm9ybWF0aW9uLCB0bXAsIHNpemVvZih0bXApLCAmY291bnQgKSkKICAgICAgICB7CiAgICAgICAgICAgIFdDSEFSICpzdHIgPSAoV0NIQVIgKikoKEtFWV9WQUxVRV9QQVJUSUFMX0lORk9STUFUSU9OICopdG1wKS0+RGF0YTsKICAgICAgICAgICAgV2lkZUNoYXJUb011bHRpQnl0ZShDUF9BQ1AsIDAsIHN0ciwgLTEsIGNvbmZpZ2ZpbGUsIHNpemVvZihjb25maWdmaWxlKSwgTlVMTCwgTlVMTCk7CiAgICAgICAgfQogICAgICAgIGlmIChjb25maWdmaWxlWzBdICE9ICcvJykgc3RyY3B5KGNvbmZpZ2ZpbGUsIEVUQ0RJUik7CgogICAgICAgIFRSQUNFKCJHbG9iYWxSZWdpc3RyeURpciBpcyAnJXMnLlxuIiwgY29uZmlnZmlsZSk7CgogICAgICAgIC8qIExvYWQgdGhlIGdsb2JhbCBIS1UgaGl2ZSBkaXJlY3RseSBmcm9tIHN5c2NvbmZkaXIgKi8KICAgICAgICBwID0gY29uZmlnZmlsZSArIHN0cmxlbihjb25maWdmaWxlKTsKICAgICAgICBzdHJjcHkocCwgU0FWRV9HTE9CQUxfUkVHQlJBTkNIX1VTRVJfREVGQVVMVCk7CiAgICAgICAgbG9hZF93aW5lX3JlZ2lzdHJ5KCBoa2V5X3VzZXJzLCBjb25maWdmaWxlICk7CgogICAgICAgIC8qIExvYWQgdGhlIGdsb2JhbCBtYWNoaW5lIGRlZmF1bHRzIGRpcmVjdGx5IGZyb20gc3lzY29uZmRpciAqLwogICAgICAgIHN0cmNweShwLCBTQVZFX0dMT0JBTF9SRUdCUkFOQ0hfTE9DQUxfTUFDSElORSk7CiAgICAgICAgbG9hZF93aW5lX3JlZ2lzdHJ5KCBoa2V5X2xvY2FsX21hY2hpbmUsIGNvbmZpZ2ZpbGUgKTsKICAgIH0KCiAgICBfc2V0X3JlZ2lzdHJ5X2xldmVscygxLDAsMCk7CgogICAgLyogbG9hZCBob21lIHJlZ2lzdHJ5IGlmIHJlcXVpcmVkICovCgogICAgcmVzID0gVFJVRTsKICAgIFJ0bEluaXRVbmljb2RlU3RyaW5nKCAmbmFtZVcsIGxvYWRfaG9tZV9yZWdfZmlsZXNXICk7CiAgICBpZiAoIU50UXVlcnlWYWx1ZUtleSggaGtleV9jb25maWcsICZuYW1lVywgS2V5VmFsdWVQYXJ0aWFsSW5mb3JtYXRpb24sIHRtcCwgc2l6ZW9mKHRtcCksICZjb3VudCApKQogICAgewogICAgICAgIFdDSEFSICpzdHIgPSAoV0NIQVIgKikoKEtFWV9WQUxVRV9QQVJUSUFMX0lORk9STUFUSU9OICopdG1wKS0+RGF0YTsKICAgICAgICByZXMgPSAhSVNfT1BUSU9OX0ZBTFNFKHN0clswXSk7CiAgICB9CiAgICBpZiAocmVzKSBfbG9hZF9ob21lX3JlZ2lzdHJ5KCBoa2V5X2xvY2FsX21hY2hpbmUsIGhrZXlfY3VycmVudF91c2VyLCBoa2V5X3VzZXJzX2RlZmF1bHQgKTsKCiAgICAvKiBzZXR1cCByZWdpc3RyeSBzYXZpbmcgKi8KCiAgICBhbGwgPSBGQUxTRTsKICAgIFJ0bEluaXRVbmljb2RlU3RyaW5nKCAmbmFtZVcsIFNhdmVPbmx5VXBkYXRlZEtleXNXICk7CiAgICBpZiAoIU50UXVlcnlWYWx1ZUtleSggaGtleV9jb25maWcsICZuYW1lVywgS2V5VmFsdWVQYXJ0aWFsSW5mb3JtYXRpb24sIHRtcCwgc2l6ZW9mKHRtcCksICZjb3VudCApKQogICAgewogICAgICAgIFdDSEFSICpzdHIgPSAoV0NIQVIgKikoKEtFWV9WQUxVRV9QQVJUSUFMX0lORk9STUFUSU9OICopdG1wKS0+RGF0YTsKICAgICAgICBhbGwgPSBJU19PUFRJT05fRkFMU0Uoc3RyWzBdKTsKICAgIH0KCiAgICBwZXJpb2QgPSAwOwogICAgUnRsSW5pdFVuaWNvZGVTdHJpbmcoICZuYW1lVywgUGVyaW9kaWNTYXZlVyApOwogICAgaWYgKCFOdFF1ZXJ5VmFsdWVLZXkoIGhrZXlfY29uZmlnLCAmbmFtZVcsIEtleVZhbHVlUGFydGlhbEluZm9ybWF0aW9uLCB0bXAsIHNpemVvZih0bXApLCAmY291bnQgKSkKICAgIHsKICAgICAgICBXQ0hBUiAqc3RyID0gKFdDSEFSICopKChLRVlfVkFMVUVfUEFSVElBTF9JTkZPUk1BVElPTiAqKXRtcCktPkRhdGE7CiAgICAgICAgcGVyaW9kID0gKGludClzdHJ0b2xXKHN0ciwgTlVMTCwgMTApOwogICAgfQoKICAgIC8qIHNldCBzYXZpbmcgbGV2ZWwgKDAgZm9yIHNhdmluZyBldmVyeXRoaW5nLCAxIGZvciBzYXZpbmcgb25seSBtb2RpZmllZCBrZXlzKSAqLwogICAgX3NldF9yZWdpc3RyeV9sZXZlbHMoMSwhYWxsLHBlcmlvZCoxMDAwKTsKCiAgICAvKiBzZXR1cCBrZXlzIHRvIHNhdmUgKi8KCiAgICByZXMgPSBUUlVFOwogICAgUnRsSW5pdFVuaWNvZGVTdHJpbmcoICZuYW1lVywgV3JpdGV0b0hvbWVSZWdpc3RyeUZpbGVzVyApOwogICAgaWYgKCFOdFF1ZXJ5VmFsdWVLZXkoIGhrZXlfY29uZmlnLCAmbmFtZVcsIEtleVZhbHVlUGFydGlhbEluZm9ybWF0aW9uLCB0bXAsIHNpemVvZih0bXApLCAmY291bnQgKSkKICAgIHsKICAgICAgICBXQ0hBUiAqc3RyID0gKFdDSEFSICopKChLRVlfVkFMVUVfUEFSVElBTF9JTkZPUk1BVElPTiAqKXRtcCktPkRhdGE7CiAgICAgICAgcmVzID0gIUlTX09QVElPTl9GQUxTRShzdHJbMF0pOwogICAgfQogICAgaWYgKHJlcykKICAgIHsKICAgICAgICBfc2F2ZV9hdF9leGl0KGhrZXlfY3VycmVudF91c2VyLCIvIiBTQVZFX0xPQ0FMX1JFR0JSQU5DSF9DVVJSRU5UX1VTRVIgKTsKICAgICAgICBfc2F2ZV9hdF9leGl0KGhrZXlfbG9jYWxfbWFjaGluZSwiLyIgU0FWRV9MT0NBTF9SRUdCUkFOQ0hfTE9DQUxfTUFDSElORSk7CiAgICAgICAgX3NhdmVfYXRfZXhpdChoa2V5X3VzZXJzX2RlZmF1bHQsIi8iIFNBVkVfTE9DQUxfUkVHQlJBTkNIX1VTRVJfREVGQVVMVCk7CiAgICB9CgogICAgTnRDbG9zZShoa2V5X3VzZXJzX2RlZmF1bHQpOwogICAgTnRDbG9zZShoa2V5X2N1cnJlbnRfdXNlcik7CiAgICBOdENsb3NlKGhrZXlfdXNlcnMpOwogICAgTnRDbG9zZShoa2V5X2xvY2FsX21hY2hpbmUpOwogICAgTnRDbG9zZShoa2V5X2NvbmZpZyk7Cn0K