LyoKICogKEMpIENvcHlyaWdodCAyMDAyCiAqIERhbmllbCBFbmdzdHL2bSwgT21pY3JvbiBDZXRpIEFCLCBkYW5pZWxAb21pY3Jvbi5zZQogKgogKiBTZWUgZmlsZSBDUkVESVRTIGZvciBsaXN0IG9mIHBlb3BsZSB3aG8gY29udHJpYnV0ZWQgdG8gdGhpcwogKiBwcm9qZWN0LgogKgogKiBUaGlzIHByb2dyYW0gaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yCiAqIG1vZGlmeSBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGFzCiAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXIgdmVyc2lvbiAyIG9mCiAqIHRoZSBMaWNlbnNlLCBvciAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLgogKgogKiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwKICogYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YKICogTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZQogKiBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQogKiBhbG9uZyB3aXRoIHRoaXMgcHJvZ3JhbTsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZQogKiBGb3VuZGF0aW9uLCBJbmMuLCA1OSBUZW1wbGUgUGxhY2UsIFN1aXRlIDMzMCwgQm9zdG9uLAogKiBNQSAwMjExMS0xMzA3IFVTQQogKi8KCi8qCiAqIExpbnV4IGkzODYgekltYWdlIGFuZCBiekltYWdlIGxvYWRpbmcKICoKICogYmFzZWQgb24gdGhlIHByb2NkdXJlIGRlc2NyaWJlZCBpbgogKiBsaW51eC9Eb2N1bWVudGF0aW9uL2kzODYvYm9vdC50eHQKICovCgojaW5jbHVkZSA8Y29tbW9uLmg+CiNpbmNsdWRlIDxhc20vaW8uaD4KI2luY2x1ZGUgPGFzbS9wdHJhY2UuaD4KI2luY2x1ZGUgPGFzbS96aW1hZ2UuaD4KI2luY2x1ZGUgPGFzbS9yZWFsbW9kZS5oPgojaW5jbHVkZSA8YXNtL2J5dGVvcmRlci5oPgojaW5jbHVkZSA8YXNtL2Jvb3RwYXJhbS5oPgojaW5jbHVkZSA8YXNtL2ljL3NjNTIwLmg+CgovKgogKiBNZW1vcnkgbGF5LW91dDoKICoKICogcmVsYXRpdmUgdG8gc2V0dXBfYmFzZSAod2hpY2ggaXMgMHg5MDAwMCBjdXJyZW50bHkpCiAqCiAqCTB4MDAwMC0weDdGRkYJUmVhbCBtb2RlIGtlcm5lbAogKgkweDgwMDAtMHg4RkZGCVN0YWNrIGFuZCBoZWFwCiAqCTB4OTAwMC0weDkwRkYJS2VybmVsIGNvbW1hbmQgbGluZQogKi8KI2RlZmluZSBERUZBVUxUX1NFVFVQX0JBU0UgIDB4OTAwMDAKI2RlZmluZSBDT01NQU5EX0xJTkVfT0ZGU0VUIDB4OTAwMAojZGVmaW5lIEhFQVBfRU5EX09GRlNFVCAgICAgMHg4ZTAwCgojZGVmaW5lIENPTU1BTkRfTElORV9TSVpFICAgMjA0OAoKc3RhdGljIHZvaWQgYnVpbGRfY29tbWFuZF9saW5lKGNoYXIgKmNvbW1hbmRfbGluZSwgaW50IGF1dG9fYm9vdCkKewoJY2hhciAqZW52X2NvbW1hbmRfbGluZTsKCgljb21tYW5kX2xpbmVbMF0gPSAnXDAnOwoKCWVudl9jb21tYW5kX2xpbmUgPSAgZ2V0ZW52KCJib290YXJncyIpOwoKCS8qIHNldCBjb25zb2xlPSBhcmd1bWVudCBpZiB3ZSB1c2UgYSBzZXJpYWwgY29uc29sZSAqLwoJaWYgKE5VTEwgPT0gc3Ryc3RyKGVudl9jb21tYW5kX2xpbmUsICJjb25zb2xlPSIpKSB7CgkJaWYgKDA9PXN0cmNtcChnZXRlbnYoInN0ZG91dCIpLCAic2VyaWFsIikpIHsKCgkJCS8qIFdlIHNlZW0gdG8gdXNlIHNlcmlhbCBjb25zb2xlICovCgkJCXNwcmludGYoY29tbWFuZF9saW5lLCAiY29uc29sZT10dHlTMCwlcyAiLAoJCQkJIGdldGVudigiYmF1ZHJhdGUiKSk7CgkJfQoJfQoKCWlmIChhdXRvX2Jvb3QpIHsKCQlzdHJjYXQoY29tbWFuZF9saW5lLCAiYXV0byAiKTsKCX0KCglpZiAoTlVMTCAhPSBlbnZfY29tbWFuZF9saW5lKSB7CgkJc3RyY2F0KGNvbW1hbmRfbGluZSwgZW52X2NvbW1hbmRfbGluZSk7Cgl9CgoKCXByaW50ZigiS2VybmVsIGNvbW1hbmQgbGluZTogXCIlc1wiXG4iLCBjb21tYW5kX2xpbmUpOwp9Cgp2b2lkICpsb2FkX3ppbWFnZShjaGFyICppbWFnZSwgdW5zaWduZWQgbG9uZyBrZXJuZWxfc2l6ZSwKCQkgIHVuc2lnbmVkIGxvbmcgaW5pdHJkX2FkZHIsIHVuc2lnbmVkIGxvbmcgaW5pdHJkX3NpemUsCgkJICBpbnQgYXV0b19ib290KQp7Cgl2b2lkICpzZXR1cF9iYXNlOwoJaW50IHNldHVwX3NpemU7CglpbnQgYm9vdHByb3RvOwoJaW50IGJpZ19pbWFnZTsKCXZvaWQgKmxvYWRfYWRkcmVzczsKCglzdHJ1Y3Qgc2V0dXBfaGVhZGVyICpoZHIgPSAoc3RydWN0IHNldHVwX2hlYWRlciAqKShpbWFnZSArIFNFVFVQX1NFQ1RTX09GRik7CgoJc2V0dXBfYmFzZSA9ICh2b2lkKilERUZBVUxUX1NFVFVQX0JBU0U7CS8qIGJhc2UgYWRkcmVzcyBmb3IgcmVhbC1tb2RlIHNlZ21lbnQgKi8KCglpZiAoS0VSTkVMX01BR0lDICE9IGhkci0+Ym9vdF9mbGFnKSB7CgkJcHJpbnRmKCJFcnJvcjogSW52YWxpZCBCb290IEZsYWcgKGZvdW5kIDB4JTA0eCwgZXhwZWN0ZWQgMHglMDR4KVxuIiwKCQkJCWhkci0+Ym9vdF9mbGFnLCBLRVJORUxfTUFHSUMpOwoJCXJldHVybiAwOwoJfSBlbHNlIHsKCQlwcmludGYoIlZhbGlkIEJvb3QgRmxhZ1xuIik7Cgl9CgoJLyogZGV0ZXJtaW5lIGJvb3QgcHJvdG9jb2wgdmVyc2lvbiAqLwoJaWYgKEtFUk5FTF9WMl9NQUdJQyA9PSBoZHItPmhlYWRlcikgewoJCXByaW50ZigiTWFnaWMgc2lnbmF0dXJlIGZvdW5kXG4iKTsKCgkJYm9vdHByb3RvID0gaGRyLT52ZXJzaW9uOwoJfSBlbHNlIHsKCQkvKiBWZXJ5IG9sZCBrZXJuZWwgKi8KCQlwcmludGYoIk1hZ2ljIHNpZ25hdHVyZSBub3QgZm91bmRcbiIpOwoJCWJvb3Rwcm90byA9IDB4MDEwMDsKCX0KCgkvKiBkZXRlcm1pbmUgc2l6ZSBvZiBzZXR1cCAqLwoJaWYgKDAgPT0gaGRyLT5zZXR1cF9zZWN0cykgewoJCXByaW50ZigiU2V0dXAgU2VjdG9ycyA9IDAgKGRlZmF1bHRpbmcgdG8gNClcbiIpOwoJCXNldHVwX3NpemUgPSA1ICogNTEyOwoJfSBlbHNlIHsKCQlzZXR1cF9zaXplID0gKGhkci0+c2V0dXBfc2VjdHMgKyAxKSAqIDUxMjsKCX0KCglwcmludGYoIlNldHVwIFNpemUgPSAweCU4LjhseFxuIiwgKHVsb25nKXNldHVwX3NpemUpOwoKCWlmIChzZXR1cF9zaXplID4gU0VUVVBfTUFYX1NJWkUpIHsKCQlwcmludGYoIkVycm9yOiBTZXR1cCBpcyB0b28gbGFyZ2UgKCVkIGJ5dGVzKVxuIiwgc2V0dXBfc2l6ZSk7Cgl9CgoJLyogRGV0ZXJtaW5lIGltYWdlIHR5cGUgKi8KCWJpZ19pbWFnZSA9IChib290cHJvdG8gPj0gMHgwMjAwKSAmJiAoaGRyLT5sb2FkZmxhZ3MgJiBCSUdfS0VSTkVMX0ZMQUcpOwoKCS8qIERldGVybWluZSBsb2FkIGFkZHJlc3MgKi8KCWxvYWRfYWRkcmVzcyA9ICh2b2lkKikoYmlnX2ltYWdlID8gQlpJTUFHRV9MT0FEX0FERFIgOiBaSU1BR0VfTE9BRF9BRERSKTsKCgkvKiBsb2FkIHNldHVwICovCglwcmludGYoIk1vdmluZyBSZWFsLU1vZGUgQ29kZSB0byAweCU4LjhseCAoJWQgYnl0ZXMpXG4iLCAodWxvbmcpc2V0dXBfYmFzZSwgc2V0dXBfc2l6ZSk7CgltZW1tb3ZlKHNldHVwX2Jhc2UsIGltYWdlLCBzZXR1cF9zaXplKTsKCglwcmludGYoIlVzaW5nIGJvb3QgcHJvdG9jb2wgdmVyc2lvbiAleC4lMDJ4XG4iLAoJICAgICAgIChib290cHJvdG8gJiAweGZmMDApID4+IDgsIGJvb3Rwcm90byAmIDB4ZmYpOwoKCWlmIChib290cHJvdG8gPT0gMHgwMTAwKSB7CgoJCSoodTE2Kikoc2V0dXBfYmFzZSArIENNRF9MSU5FX01BR0lDX09GRikgPSBDT01NQU5EX0xJTkVfTUFHSUM7CgkJKih1MTYqKShzZXR1cF9iYXNlICsgQ01EX0xJTkVfT0ZGU0VUX09GRikgPSBDT01NQU5EX0xJTkVfT0ZGU0VUOwoKCQkvKiBBIHZlcnkgb2xkIGtlcm5lbCBNVVNUIGhhdmUgaXRzIHJlYWwtbW9kZSBjb2RlCgkJICogbG9hZGVkIGF0IDB4OTAwMDAgKi8KCgkJaWYgKCh1MzIpc2V0dXBfYmFzZSAhPSAweDkwMDAwKSB7CgkJCS8qIENvcHkgdGhlIHJlYWwtbW9kZSBrZXJuZWwgKi8KCQkJbWVtbW92ZSgodm9pZCopMHg5MDAwMCwgc2V0dXBfYmFzZSwgc2V0dXBfc2l6ZSk7CgkJCS8qIENvcHkgdGhlIGNvbW1hbmQgbGluZSAqLwoJCQltZW1tb3ZlKCh2b2lkKikweDk5MDAwLCBzZXR1cF9iYXNlK0NPTU1BTkRfTElORV9PRkZTRVQsCgkJCSAgICAgICBDT01NQU5EX0xJTkVfU0laRSk7CgoJCQlzZXR1cF9iYXNlID0gKHZvaWQqKTB4OTAwMDA7CQkgLyogUmVsb2NhdGVkICovCgkJfQoKCQkvKiBJdCBpcyByZWNvbW1lbmRlZCB0byBjbGVhciBtZW1vcnkgdXAgdG8gdGhlIDMySyBtYXJrICovCgkJbWVtc2V0KCh2b2lkKikweDkwMDAwICsgc2V0dXBfc2l6ZSwgMCwgU0VUVVBfTUFYX1NJWkUtc2V0dXBfc2l6ZSk7Cgl9CgoJLyogV2UgYXJlIG5vdyBzZXR0aW5nIHVwIHRoZSByZWFsLW1vZGUgdmVyc2lvbiBvZiB0aGUgaGVhZGVyICovCgloZHIgPSAoc3RydWN0IHNldHVwX2hlYWRlciAqKShzZXR1cF9iYXNlICsgU0VUVVBfU0VDVFNfT0ZGKTsKCglpZiAoYm9vdHByb3RvID49IDB4MDIwMCkgewoJCWhkci0+dHlwZV9vZl9sb2FkZXIgPSA4OwoKCQlpZiAoaGRyLT5zZXR1cF9zZWN0cyA+PSAxNSkKCQkJcHJpbnRmKCJMaW51eCBrZXJuZWwgdmVyc2lvbiAlc1xuIiwgKGNoYXIgKikKCQkJCQkoc2V0dXBfYmFzZSArIChoZHItPmtlcm5lbF92ZXJzaW9uICsgMHgyMDApKSk7CgkJZWxzZQoJCQlwcmludGYoIlNldHVwIFNlY3RvcnMgPCAxNSAtIENhbm5vdCBwcmludCBrZXJuZWwgdmVyc2lvbi5cbiIpOwoKCQlpZiAoaW5pdHJkX2FkZHIpIHsKCQkJcHJpbnRmKCJJbml0aWFsIFJBTSBkaXNrIGF0IGxpbmVhciBhZGRyZXNzIDB4JTA4bHgsIHNpemUgJWxkIGJ5dGVzXG4iLAoJCQkgICAgICAgaW5pdHJkX2FkZHIsIGluaXRyZF9zaXplKTsKCgkJCWhkci0+cmFtZGlza19pbWFnZSA9IGluaXRyZF9hZGRyOwoJCQloZHItPnJhbWRpc2tfc2l6ZSA9IGluaXRyZF9zaXplOwoJCX0KCX0KCglpZiAoYm9vdHByb3RvID49IDB4MDIwMSkgewoJCWhkci0+aGVhcF9lbmRfcHRyID0gSEVBUF9FTkRfT0ZGU0VUOwoJCWhkci0+bG9hZGZsYWdzIHw9IEhFQVBfRkxBRzsKCX0KCglpZiAoYm9vdHByb3RvID49IDB4MDIwMikgewoJCWhkci0+Y21kX2xpbmVfcHRyID0gKHUzMilzZXR1cF9iYXNlICsgQ09NTUFORF9MSU5FX09GRlNFVDsKCX0gZWxzZSBpZiAoYm9vdHByb3RvID49IDB4MDIwMCkgewoKCQkqKHUxNiopKHNldHVwX2Jhc2UgKyBDTURfTElORV9NQUdJQ19PRkYpID0gQ09NTUFORF9MSU5FX01BR0lDOwoJCSoodTE2Kikoc2V0dXBfYmFzZSArIENNRF9MSU5FX09GRlNFVF9PRkYpID0gQ09NTUFORF9MSU5FX09GRlNFVDsKCgkJaGRyLT5zZXR1cF9tb3ZlX3NpemUgPSAweDkxMDA7Cgl9CgoJaWYgKGJvb3Rwcm90byA+PSAweDAyMDQpCgkJa2VybmVsX3NpemUgPSBoZHItPnN5c3NpemUgKiAxNjsKCWVsc2UKCQlrZXJuZWxfc2l6ZSAtPSBzZXR1cF9zaXplOwoKCglpZiAoYmlnX2ltYWdlKSB7CgkJaWYgKChrZXJuZWxfc2l6ZSkgPiBCWklNQUdFX01BWF9TSVpFKSB7CgkJCXByaW50ZigiRXJyb3I6IGJ6SW1hZ2Uga2VybmVsIHRvbyBiaWchIChzaXplOiAlbGQsIG1heDogJWQpXG4iLAoJCQkgICAgICAga2VybmVsX3NpemUsIEJaSU1BR0VfTUFYX1NJWkUpOwoJCQlyZXR1cm4gMDsKCQl9CgoJfSBlbHNlIGlmICgoa2VybmVsX3NpemUpID4gWklNQUdFX01BWF9TSVpFKSB7CgkJcHJpbnRmKCJFcnJvcjogekltYWdlIGtlcm5lbCB0b28gYmlnISAoc2l6ZTogJWxkLCBtYXg6ICVkKVxuIiwKCQkgICAgICAga2VybmVsX3NpemUsIFpJTUFHRV9NQVhfU0laRSk7CgkJcmV0dXJuIDA7Cgl9CgoJLyogYnVpbGQgY29tbWFuZCBsaW5lIGF0IENPTU1BTkRfTElORV9PRkZTRVQgKi8KCWJ1aWxkX2NvbW1hbmRfbGluZShzZXR1cF9iYXNlICsgQ09NTUFORF9MSU5FX09GRlNFVCwgYXV0b19ib290KTsKCglwcmludGYoIkxvYWRpbmcgJWN6SW1hZ2UgYXQgYWRkcmVzcyAweCUwOHggKCVsZCBieXRlcylcbiIsIGJpZ19pbWFnZSA/ICdiJyA6ICcgJywKCSAgICAgICAodTMyKWxvYWRfYWRkcmVzcywga2VybmVsX3NpemUpOwoKCgltZW1tb3ZlKGxvYWRfYWRkcmVzcywgaW1hZ2UgKyBzZXR1cF9zaXplLCBrZXJuZWxfc2l6ZSk7CgoJLyogcmVhZHkgZm9yIGJvb3RpbmcgKi8KCXJldHVybiBzZXR1cF9iYXNlOwp9Cgp2b2lkIGJvb3RfemltYWdlKHZvaWQgKnNldHVwX2Jhc2UpCnsKCXN0cnVjdCBwdF9yZWdzIHJlZ3M7CgoJbWVtc2V0KCZyZWdzLCAwLCBzaXplb2Yoc3RydWN0IHB0X3JlZ3MpKTsKCXJlZ3MueGRzID0gKHUzMilzZXR1cF9iYXNlID4+IDQ7CglyZWdzLnhlcyA9IHJlZ3MueGRzOwoJcmVncy54c3MgPSByZWdzLnhkczsKCXJlZ3MuZXNwID0gMHg5MDAwOwoJcmVncy5lZmxhZ3MgPSAwOwoJZW50ZXJfcmVhbG1vZGUoKCh1MzIpc2V0dXBfYmFzZStTRVRVUF9TVEFSVF9PRkZTRVQpPj40LCAwLCAmcmVncywgJnJlZ3MpOwp9CgppbnQgZG9femJvb3QgKGNtZF90YmxfdCAqY21kdHAsIGludCBmbGFnLCBpbnQgYXJnYywgY2hhciAqIGNvbnN0IGFyZ3ZbXSkKewoJdm9pZCAqYmFzZV9wdHI7Cgl2b2lkICpiekltYWdlX2FkZHIgPSBOVUxMOwoJY2hhciAqczsKCXVsb25nIGJ6SW1hZ2Vfc2l6ZSA9IDA7CgoJZGlzYWJsZV9pbnRlcnJ1cHRzKCk7CgoJLyogU2V0dXAgYm9hcmQgZm9yIG1heGltdW0gUEMvQVQgQ29tcGF0aWJpbGl0eSAqLwoJc2V0dXBfcGNhdF9jb21wYXRpYmlsaXR5KCk7CgoJaWYgKGFyZ2MgPj0gMikKCQkvKiBhcmd2WzFdIGhvbGRzIHRoZSBhZGRyZXNzIG9mIHRoZSBiekltYWdlICovCgkJcyA9IGFyZ3ZbMV07CgllbHNlCgkJcyA9IGdldGVudigiZmlsZWFkZHIiKTsKCglpZiAocykKCQliekltYWdlX2FkZHIgPSAodm9pZCAqKXNpbXBsZV9zdHJ0b3VsKHMsIE5VTEwsIDE2KTsKCglpZiAoYXJnYyA+PSAzKQoJCS8qIGFyZ3ZbMl0gaG9sZHMgdGhlIHNpemUgb2YgdGhlIGJ6SW1hZ2UgKi8KCQliekltYWdlX3NpemUgPSBzaW1wbGVfc3RydG91bChhcmd2WzJdLCBOVUxMLCAxNik7CgoJLyogTGV0cyBsb29rIGZvciovCgliYXNlX3B0ciA9IGxvYWRfemltYWdlIChiekltYWdlX2FkZHIsIGJ6SW1hZ2Vfc2l6ZSwgMCwgMCwgMCk7CgoJaWYgKE5VTEwgPT0gYmFzZV9wdHIpIHsKCQlwcmludGYgKCIjIyBLZXJuZWwgbG9hZGluZyBmYWlsZWQgLi4uXG4iKTsKCX0gZWxzZSB7CgkJcHJpbnRmICgiIyMgVHJhbnNmZXJyaW5nIGNvbnRyb2wgdG8gTGludXggKGF0IGFkZHJlc3MgJTA4eCkgLi4uXG4iLAoJCQkodTMyKWJhc2VfcHRyKTsKCgkJLyogd2UgYXNzdW1lIHRoYXQgdGhlIGtlcm5lbCBpcyBpbiBwbGFjZSAqLwoJCXByaW50ZigiXG5TdGFydGluZyBrZXJuZWwgLi4uXG5cbiIpOwoKCQlib290X3ppbWFnZShiYXNlX3B0cik7CgkJLyogZG9lcyBub3QgcmV0dXJuICovCgl9CgoJcmV0dXJuIC0xOwp9CgpVX0JPT1RfQ01EKAoJemJvb3QsIDIsIDAsCWRvX3pib290LAoJIkJvb3QgYnpJbWFnZSIsCgkiIgopOwo=