LyogbWVtcmVnaW9uX2RpcmVjdC5jCiAqCiAqIENvcHlyaWdodCCpIDIwMTAgLSAyMDEzIFVOSVNZUyBDT1JQT1JBVElPTgogKiBBbGwgcmlnaHRzIHJlc2VydmVkLgogKgogKiBUaGlzIHByb2dyYW0gaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeQogKiBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieQogKiB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXIgdmVyc2lvbiAyIG9mIHRoZSBMaWNlbnNlLCBvciAoYXQKICogeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLgogKgogKiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0CiAqIFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YKICogTUVSQ0hBTlRBQklMSVRZIE9SIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLCBHT09EIFRJVExFIG9yCiAqIE5PTiBJTkZSSU5HRU1FTlQuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlCiAqIGRldGFpbHMuCiAqLwoKLyoKICogIFRoaXMgaXMgYW4gaW1wbGVtZW50YXRpb24gb2YgbWVtb3J5IHJlZ2lvbnMgdGhhdCBjYW4gYmUgdXNlZCB0byByZWFkL3dyaXRlCiAqICBjaGFubmVsIG1lbW9yeSAoaW4gbWFpbiBtZW1vcnkgb2YgdGhlIGhvc3Qgc3lzdGVtKSBmcm9tIGNvZGUgcnVubmluZyBpbgogKiAgYSB2aXJ0dWFsIHBhcnRpdGlvbi4KICovCiNpbmNsdWRlICJ1bmlrbG9nLmgiCiNpbmNsdWRlICJ0aW1za21vZC5oIgojaW5jbHVkZSAibWVtcmVnaW9uLmgiCgojZGVmaW5lIE1ZRFJWTkFNRSAibWVtcmVnaW9uIgoKc3RydWN0IE1FTVJFR0lPTl9UYWcgewoJSE9TVEFERFJFU1MgcGh5c2FkZHI7Cgl1bG9uZyBuYnl0ZXM7Cgl2b2lkICptYXBwZWQ7CglCT09MIHJlcXVlc3RlZDsKCUJPT0wgb3ZlcmxhcHBlZDsKfTsKCnN0YXRpYyBCT09MIG1hcGl0KE1FTVJFR0lPTiAqbWVtcmVnaW9uKTsKc3RhdGljIHZvaWQgdW5tYXBpdChNRU1SRUdJT04gKm1lbXJlZ2lvbik7CgpNRU1SRUdJT04gKgp2aXNvcl9tZW1yZWdpb25fY3JlYXRlKEhPU1RBRERSRVNTIHBoeXNhZGRyLCB1bG9uZyBuYnl0ZXMpCnsKCU1FTVJFR0lPTiAqcmMgPSBOVUxMOwoJTUVNUkVHSU9OICptZW1yZWdpb24gPSBremFsbG9jKHNpemVvZihNRU1SRUdJT04pLAoJCQkJICAgICAgIEdGUF9LRVJORUwgfCBfX0dGUF9OT1JFVFJZKTsKCWlmIChtZW1yZWdpb24gPT0gTlVMTCkgewoJCUVSUkRSVigidmlzb3JfbWVtcmVnaW9uX2NyZWF0ZSBhbGxvY2F0aW9uIGZhaWxlZCIpOwoJCXJldHVybiBOVUxMOwoJfQoJbWVtcmVnaW9uLT5waHlzYWRkciA9IHBoeXNhZGRyOwoJbWVtcmVnaW9uLT5uYnl0ZXMgPSBuYnl0ZXM7CgltZW1yZWdpb24tPm92ZXJsYXBwZWQgPSBGQUxTRTsKCWlmICghbWFwaXQobWVtcmVnaW9uKSkgewoJCXJjID0gTlVMTDsKCQlnb3RvIEF3YXk7Cgl9CglyYyA9IG1lbXJlZ2lvbjsKQXdheToKCWlmIChyYyA9PSBOVUxMKSB7CgkJaWYgKG1lbXJlZ2lvbiAhPSBOVUxMKSB7CgkJCXZpc29yX21lbXJlZ2lvbl9kZXN0cm95KG1lbXJlZ2lvbik7CgkJCW1lbXJlZ2lvbiA9IE5VTEw7CgkJfQoJfQoJcmV0dXJuIHJjOwp9CkVYUE9SVF9TWU1CT0xfR1BMKHZpc29yX21lbXJlZ2lvbl9jcmVhdGUpOwoKTUVNUkVHSU9OICoKdmlzb3JfbWVtcmVnaW9uX2NyZWF0ZV9vdmVybGFwcGVkKE1FTVJFR0lPTiAqcGFyZW50LCB1bG9uZyBvZmZzZXQsIHVsb25nIG5ieXRlcykKewoJTUVNUkVHSU9OICptZW1yZWdpb24gPSBOVUxMOwoKCWlmIChwYXJlbnQgPT0gTlVMTCkgewoJCUVSUkRSVigiJXMgcGFyZW50IGlzIE5VTEwiLCBfX2Z1bmNfXyk7CgkJcmV0dXJuIE5VTEw7Cgl9CglpZiAocGFyZW50LT5tYXBwZWQgPT0gTlVMTCkgewoJCUVSUkRSVigiJXMgcGFyZW50IGlzIG5vdCBtYXBwZWQhIiwgX19mdW5jX18pOwoJCXJldHVybiBOVUxMOwoJfQoJaWYgKChvZmZzZXQgPj0gcGFyZW50LT5uYnl0ZXMpIHx8CgkgICAgKChvZmZzZXQgKyBuYnl0ZXMpID49IHBhcmVudC0+bmJ5dGVzKSkgewoJCUVSUkRSVigiJXMgcmFuZ2UgKCVsdSwlbHUpIG91dCBvZiBwYXJlbnQgcmFuZ2UiLAoJCSAgICAgICBfX2Z1bmNfXywgb2Zmc2V0LCBuYnl0ZXMpOwoJCXJldHVybiBOVUxMOwoJfQoJbWVtcmVnaW9uID0ga3phbGxvYyhzaXplb2YoTUVNUkVHSU9OKSwgR0ZQX0tFUk5FTHxfX0dGUF9OT1JFVFJZKTsKCWlmIChtZW1yZWdpb24gPT0gTlVMTCkgewoJCUVSUkRSVigiJXMgYWxsb2NhdGlvbiBmYWlsZWQiLCBfX2Z1bmNfXyk7CgkJcmV0dXJuIE5VTEw7Cgl9CgoJbWVtcmVnaW9uLT5waHlzYWRkciA9IHBhcmVudC0+cGh5c2FkZHIgKyBvZmZzZXQ7CgltZW1yZWdpb24tPm5ieXRlcyA9IG5ieXRlczsKCW1lbXJlZ2lvbi0+bWFwcGVkID0gKCh1OCAqKSAocGFyZW50LT5tYXBwZWQpKSArIG9mZnNldDsKCW1lbXJlZ2lvbi0+cmVxdWVzdGVkID0gRkFMU0U7CgltZW1yZWdpb24tPm92ZXJsYXBwZWQgPSBUUlVFOwoJcmV0dXJuIG1lbXJlZ2lvbjsKfQpFWFBPUlRfU1lNQk9MX0dQTCh2aXNvcl9tZW1yZWdpb25fY3JlYXRlX292ZXJsYXBwZWQpOwoKCnN0YXRpYyBCT09MCm1hcGl0KE1FTVJFR0lPTiAqbWVtcmVnaW9uKQp7Cgl1bG9uZyBwaHlzYWRkciA9ICh1bG9uZykgKG1lbXJlZ2lvbi0+cGh5c2FkZHIpOwoJdWxvbmcgbmJ5dGVzID0gbWVtcmVnaW9uLT5uYnl0ZXM7CgoJbWVtcmVnaW9uLT5yZXF1ZXN0ZWQgPSBGQUxTRTsKCWlmICghcmVxdWVzdF9tZW1fcmVnaW9uKHBoeXNhZGRyLCBuYnl0ZXMsIE1ZRFJWTkFNRSkpCgkJRVJSRFJWKCJjYW5ub3QgcmVzZXJ2ZSBjaGFubmVsIG1lbW9yeSBAMHglbHggZm9yIDB4JWx4LS0gbm8gYmlnIGRlYWwiLCBwaHlzYWRkciwgbmJ5dGVzKTsKCWVsc2UKCQltZW1yZWdpb24tPnJlcXVlc3RlZCA9IFRSVUU7CgltZW1yZWdpb24tPm1hcHBlZCA9IGlvcmVtYXBfY2FjaGUocGh5c2FkZHIsIG5ieXRlcyk7CglpZiAobWVtcmVnaW9uLT5tYXBwZWQgPT0gTlVMTCkgewoJCUVSUkRSVigiY2Fubm90IGlvcmVtYXBfY2FjaGUgY2hhbm5lbCBtZW1vcnkgQDB4JWx4IGZvciAweCVseCIsCgkJICAgICAgIHBoeXNhZGRyLCBuYnl0ZXMpOwoJCXJldHVybiBGQUxTRTsKCX0KCXJldHVybiBUUlVFOwp9CgpzdGF0aWMgdm9pZAp1bm1hcGl0KE1FTVJFR0lPTiAqbWVtcmVnaW9uKQp7CglpZiAobWVtcmVnaW9uLT5tYXBwZWQgIT0gTlVMTCkgewoJCWlvdW5tYXAobWVtcmVnaW9uLT5tYXBwZWQpOwoJCW1lbXJlZ2lvbi0+bWFwcGVkID0gTlVMTDsKCX0KCWlmIChtZW1yZWdpb24tPnJlcXVlc3RlZCkgewoJCXJlbGVhc2VfbWVtX3JlZ2lvbigodWxvbmcpIChtZW1yZWdpb24tPnBoeXNhZGRyKSwKCQkJCSAgIG1lbXJlZ2lvbi0+bmJ5dGVzKTsKCQltZW1yZWdpb24tPnJlcXVlc3RlZCA9IEZBTFNFOwoJfQp9CgpIT1NUQUREUkVTUwp2aXNvcl9tZW1yZWdpb25fZ2V0X3BoeXNhZGRyKE1FTVJFR0lPTiAqbWVtcmVnaW9uKQp7CglyZXR1cm4gbWVtcmVnaW9uLT5waHlzYWRkcjsKfQpFWFBPUlRfU1lNQk9MX0dQTCh2aXNvcl9tZW1yZWdpb25fZ2V0X3BoeXNhZGRyKTsKCnVsb25nCnZpc29yX21lbXJlZ2lvbl9nZXRfbmJ5dGVzKE1FTVJFR0lPTiAqbWVtcmVnaW9uKQp7CglyZXR1cm4gbWVtcmVnaW9uLT5uYnl0ZXM7Cn0KRVhQT1JUX1NZTUJPTF9HUEwodmlzb3JfbWVtcmVnaW9uX2dldF9uYnl0ZXMpOwoKdm9pZCAqCnZpc29yX21lbXJlZ2lvbl9nZXRfcG9pbnRlcihNRU1SRUdJT04gKm1lbXJlZ2lvbikKewoJcmV0dXJuIG1lbXJlZ2lvbi0+bWFwcGVkOwp9CkVYUE9SVF9TWU1CT0xfR1BMKHZpc29yX21lbXJlZ2lvbl9nZXRfcG9pbnRlcik7CgppbnQKdmlzb3JfbWVtcmVnaW9uX3Jlc2l6ZShNRU1SRUdJT04gKm1lbXJlZ2lvbiwgdWxvbmcgbmV3c2l6ZSkKewoJaWYgKG5ld3NpemUgPT0gbWVtcmVnaW9uLT5uYnl0ZXMpCgkJcmV0dXJuIDA7CglpZiAobWVtcmVnaW9uLT5vdmVybGFwcGVkKQoJCS8qIG5vIGVycm9yIGNoZWNrIGhlcmUgLSB3ZSBubyBsb25nZXIga25vdyB0aGUKCQkgKiBwYXJlbnQncyByYW5nZSEKCQkgKi8KCQltZW1yZWdpb24tPm5ieXRlcyA9IG5ld3NpemU7CgllbHNlIHsKCQl1bm1hcGl0KG1lbXJlZ2lvbik7CgkJbWVtcmVnaW9uLT5uYnl0ZXMgPSBuZXdzaXplOwoJCWlmICghbWFwaXQobWVtcmVnaW9uKSkKCQkJcmV0dXJuIC0xOwoJfQoJcmV0dXJuIDA7Cn0KRVhQT1JUX1NZTUJPTF9HUEwodmlzb3JfbWVtcmVnaW9uX3Jlc2l6ZSk7CgoKc3RhdGljIGludAptZW1yZWdpb25fcmVhZHdyaXRlKEJPT0wgaXNfd3JpdGUsCgkJICAgIE1FTVJFR0lPTiAqbWVtcmVnaW9uLCB1bG9uZyBvZmZzZXQsCgkJICAgIHZvaWQgKmxvY2FsLCB1bG9uZyBuYnl0ZXMpCnsKCWlmIChvZmZzZXQgKyBuYnl0ZXMgPiBtZW1yZWdpb24tPm5ieXRlcykgewoJCUVSUkRSVigibWVtcmVnaW9uX3JlYWR3cml0ZSBvZmZzZXQgb3V0IG9mIHJhbmdlISEiKTsKCQlyZXR1cm4gLUVGQVVMVDsKCX0KCWlmIChpc193cml0ZSkKCQltZW1jcHlfdG9pbyhtZW1yZWdpb24tPm1hcHBlZCArIG9mZnNldCwgbG9jYWwsIG5ieXRlcyk7CgllbHNlCgkJbWVtY3B5X2Zyb21pbyhsb2NhbCwgbWVtcmVnaW9uLT5tYXBwZWQgKyBvZmZzZXQsIG5ieXRlcyk7CgoJcmV0dXJuIDA7Cn0KCmludAp2aXNvcl9tZW1yZWdpb25fcmVhZChNRU1SRUdJT04gKm1lbXJlZ2lvbiwgdWxvbmcgb2Zmc2V0LCB2b2lkICpkZXN0LAoJCSAgICAgdWxvbmcgbmJ5dGVzKQp7CglyZXR1cm4gbWVtcmVnaW9uX3JlYWR3cml0ZShGQUxTRSwgbWVtcmVnaW9uLCBvZmZzZXQsIGRlc3QsIG5ieXRlcyk7Cn0KRVhQT1JUX1NZTUJPTF9HUEwodmlzb3JfbWVtcmVnaW9uX3JlYWQpOwoKaW50CnZpc29yX21lbXJlZ2lvbl93cml0ZShNRU1SRUdJT04gKm1lbXJlZ2lvbiwgdWxvbmcgb2Zmc2V0LCB2b2lkICpzcmMsCgkJICAgICAgdWxvbmcgbmJ5dGVzKQp7CglyZXR1cm4gbWVtcmVnaW9uX3JlYWR3cml0ZShUUlVFLCBtZW1yZWdpb24sIG9mZnNldCwgc3JjLCBuYnl0ZXMpOwp9CkVYUE9SVF9TWU1CT0xfR1BMKHZpc29yX21lbXJlZ2lvbl93cml0ZSk7Cgp2b2lkCnZpc29yX21lbXJlZ2lvbl9kZXN0cm95KE1FTVJFR0lPTiAqbWVtcmVnaW9uKQp7CglpZiAobWVtcmVnaW9uID09IE5VTEwpCgkJcmV0dXJuOwoJaWYgKCFtZW1yZWdpb24tPm92ZXJsYXBwZWQpCgkJdW5tYXBpdChtZW1yZWdpb24pOwoJa2ZyZWUobWVtcmVnaW9uKTsKfQpFWFBPUlRfU1lNQk9MX0dQTCh2aXNvcl9tZW1yZWdpb25fZGVzdHJveSk7Cgo=