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