LyogUG9ydGlvbnMgb2YgdGhpcyBmaWxlIGFyZSBzdWJqZWN0IHRvIHRoZSBmb2xsb3dpbmcgY29weXJpZ2h0KHMpLiAgU2VlCiAqIHRoZSBOZXQtU05NUCdzIENPUFlJTkcgZmlsZSBmb3IgbW9yZSBkZXRhaWxzIGFuZCBvdGhlciBjb3B5cmlnaHRzCiAqIHRoYXQgbWF5IGFwcGx5OgogKi8KLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgoJQ29weXJpZ2h0IDE5ODksIDE5OTEsIDE5OTIgYnkgQ2FybmVnaWUgTWVsbG9uIFVuaXZlcnNpdHkKCiAgICAgICAgICAgICAgICAgICAgICBBbGwgUmlnaHRzIFJlc2VydmVkCgpQZXJtaXNzaW9uIHRvIHVzZSwgY29weSwgbW9kaWZ5LCBhbmQgZGlzdHJpYnV0ZSB0aGlzIHNvZnR3YXJlIGFuZCBpdHMKZG9jdW1lbnRhdGlvbiBmb3IgYW55IHB1cnBvc2UgYW5kIHdpdGhvdXQgZmVlIGlzIGhlcmVieSBncmFudGVkLApwcm92aWRlZCB0aGF0IHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlIGFwcGVhciBpbiBhbGwgY29waWVzIGFuZCB0aGF0CmJvdGggdGhhdCBjb3B5cmlnaHQgbm90aWNlIGFuZCB0aGlzIHBlcm1pc3Npb24gbm90aWNlIGFwcGVhciBpbgpzdXBwb3J0aW5nIGRvY3VtZW50YXRpb24sIGFuZCB0aGF0IHRoZSBuYW1lIG9mIENNVSBub3QgYmUKdXNlZCBpbiBhZHZlcnRpc2luZyBvciBwdWJsaWNpdHkgcGVydGFpbmluZyB0byBkaXN0cmlidXRpb24gb2YgdGhlCnNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMsIHdyaXR0ZW4gcHJpb3IgcGVybWlzc2lvbi4KCkNNVSBESVNDTEFJTVMgQUxMIFdBUlJBTlRJRVMgV0lUSCBSRUdBUkQgVE8gVEhJUyBTT0ZUV0FSRSwgSU5DTFVESU5HCkFMTCBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTLCBJTiBOTyBFVkVOVCBTSEFMTApDTVUgQkUgTElBQkxFIEZPUiBBTlkgU1BFQ0lBTCwgSU5ESVJFQ1QgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIE9SCkFOWSBEQU1BR0VTIFdIQVRTT0VWRVIgUkVTVUxUSU5HIEZST00gTE9TUyBPRiBVU0UsIERBVEEgT1IgUFJPRklUUywKV0hFVEhFUiBJTiBBTiBBQ1RJT04gT0YgQ09OVFJBQ1QsIE5FR0xJR0VOQ0UgT1IgT1RIRVIgVE9SVElPVVMgQUNUSU9OLApBUklTSU5HIE9VVCBPRiBPUiBJTiBDT05ORUNUSU9OIFdJVEggVEhFIFVTRSBPUiBQRVJGT1JNQU5DRSBPRiBUSElTClNPRlRXQVJFLgoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCi8qCiAqIFBvcnRpb25zIG9mIHRoaXMgZmlsZSBhcmUgY29weXJpZ2h0ZWQgYnk6CiAqIENvcHlyaWdodCBDb3B5cmlnaHQgMjAwMyBTdW4gTWljcm9zeXN0ZW1zLCBJbmMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCiAqIFVzZSBpcyBzdWJqZWN0IHRvIGxpY2Vuc2UgdGVybXMgc3BlY2lmaWVkIGluIHRoZSBDT1BZSU5HIGZpbGUKICogZGlzdHJpYnV0ZWQgd2l0aCB0aGUgTmV0LVNOTVAgcGFja2FnZS4KICovCgovKiogQGRlZmdyb3VwIGxpYnJhcnkgVGhlIE5ldC1TTk1QIGxpYnJhcnkKICogIEB7CiAqLwovKgogKiBzbm1wX2FwaS5jIC0gQVBJIGZvciBhY2Nlc3MgdG8gc25tcC4KICovCiNpbmNsdWRlIDxuZXQtc25tcC9uZXQtc25tcC1jb25maWcuaD4KCiNpbmNsdWRlIDxzdGRpby5oPgojaW5jbHVkZSA8Y3R5cGUuaD4KI2lmIEhBVkVfU1RETElCX0gKI2luY2x1ZGUgPHN0ZGxpYi5oPgojZW5kaWYKI2lmIEhBVkVfU1RSSU5HX0gKI2luY2x1ZGUgPHN0cmluZy5oPgojZWxzZQojaW5jbHVkZSA8c3RyaW5ncy5oPgojZW5kaWYKI2lmIEhBVkVfVU5JU1REX0gKI2luY2x1ZGUgPHVuaXN0ZC5oPgojZW5kaWYKI2luY2x1ZGUgPHN5cy90eXBlcy5oPgojaWYgSEFWRV9TWVNfUEFSQU1fSAojaW5jbHVkZSA8c3lzL3BhcmFtLmg+CiNlbmRpZgojaWYgVElNRV9XSVRIX1NZU19USU1FCiMgaWZkZWYgV0lOMzIKIyAgaW5jbHVkZSA8c3lzL3RpbWViLmg+CiMgZWxzZQojICBpbmNsdWRlIDxzeXMvdGltZS5oPgojIGVuZGlmCiMgaW5jbHVkZSA8dGltZS5oPgojZWxzZQojIGlmIEhBVkVfU1lTX1RJTUVfSAojICBpbmNsdWRlIDxzeXMvdGltZS5oPgojIGVsc2UKIyAgaW5jbHVkZSA8dGltZS5oPgojIGVuZGlmCiNlbmRpZgojaWYgSEFWRV9ORVRJTkVUX0lOX0gKI2luY2x1ZGUgPG5ldGluZXQvaW4uaD4KI2VuZGlmCiNpZiBIQVZFX0FSUEFfSU5FVF9ICiNpbmNsdWRlIDxhcnBhL2luZXQuaD4KI2VuZGlmCiNpZiBIQVZFX1NZU19TRUxFQ1RfSAojaW5jbHVkZSA8c3lzL3NlbGVjdC5oPgojZW5kaWYKI2lmIEhBVkVfSU9fSAojaW5jbHVkZSA8aW8uaD4KI2VuZGlmCiNpZiBIQVZFX1dJTlNPQ0tfSAojaW5jbHVkZSA8d2luc29jay5oPgojZW5kaWYKI2lmIEhBVkVfU1lTX1NPQ0tFVF9ICiNpbmNsdWRlIDxzeXMvc29ja2V0Lmg+CiNlbmRpZgojaWYgSEFWRV9TWVNfVU5fSAojaW5jbHVkZSA8c3lzL3VuLmg+CiNlbmRpZgojaWYgSEFWRV9ORVREQl9ICiNpbmNsdWRlIDxuZXRkYi5oPgojZW5kaWYKI2lmIEhBVkVfTkVUX0lGX0RMX0gKI2lmbmRlZiBkeW5peAojaW5jbHVkZSA8bmV0L2lmX2RsLmg+CiNlbHNlCiNpbmNsdWRlIDxzeXMvbmV0L2lmX2RsLmg+CiNlbmRpZgojZW5kaWYKI2luY2x1ZGUgPGVycm5vLmg+CgojaWYgSEFWRV9MT0NBTEVfSAojaW5jbHVkZSA8bG9jYWxlLmg+CiNlbmRpZgoKI2lmIEhBVkVfRE1BTExPQ19ICiNpbmNsdWRlIDxkbWFsbG9jLmg+CiNlbmRpZgoKI2RlZmluZSBTTk1QX05FRURfUkVRVUVTVF9MSVNUCiNpbmNsdWRlIDxuZXQtc25tcC90eXBlcy5oPgojaW5jbHVkZSA8bmV0LXNubXAvb3V0cHV0X2FwaS5oPgojaW5jbHVkZSA8bmV0LXNubXAvY29uZmlnX2FwaS5oPgojaW5jbHVkZSA8bmV0LXNubXAvdXRpbGl0aWVzLmg+CgojaW5jbHVkZSA8bmV0LXNubXAvbGlicmFyeS9hc24xLmg+CiNpbmNsdWRlIDxuZXQtc25tcC9saWJyYXJ5L3NubXAuaD4gICAgICAvKiBmb3IgeGR1bXAgJiB7YnVpbGQscGFyc2V9X3Zhcl9vcCAqLwojaW5jbHVkZSA8bmV0LXNubXAvbGlicmFyeS9zbm1wX2FwaS5oPgojaW5jbHVkZSA8bmV0LXNubXAvbGlicmFyeS9zbm1wX2NsaWVudC5oPgojaW5jbHVkZSA8bmV0LXNubXAvbGlicmFyeS9wYXJzZS5oPgojaW5jbHVkZSA8bmV0LXNubXAvbGlicmFyeS9taWIuaD4KI2luY2x1ZGUgPG5ldC1zbm1wL2xpYnJhcnkvaW50NjQuaD4KI2luY2x1ZGUgPG5ldC1zbm1wL2xpYnJhcnkvc25tcHYzLmg+CiNpbmNsdWRlIDxuZXQtc25tcC9saWJyYXJ5L2NhbGxiYWNrLmg+CiNpbmNsdWRlIDxuZXQtc25tcC9saWJyYXJ5L2NvbnRhaW5lci5oPgojaW5jbHVkZSA8bmV0LXNubXAvbGlicmFyeS9zbm1wX3NlY21vZC5oPgojaWZkZWYgTkVUU05NUF9TRUNNT0RfVVNNCiNpbmNsdWRlIDxuZXQtc25tcC9saWJyYXJ5L3NubXB1c20uaD4KI2VuZGlmCiNpZmRlZiBORVRTTk1QX1NFQ01PRF9LU00KI2luY2x1ZGUgPG5ldC1zbm1wL2xpYnJhcnkvc25tcGtzbS5oPgojZW5kaWYKI2luY2x1ZGUgPG5ldC1zbm1wL2xpYnJhcnkva2V5dG9vbHMuaD4KI2luY2x1ZGUgPG5ldC1zbm1wL2xpYnJhcnkvbGNkX3RpbWUuaD4KI2luY2x1ZGUgPG5ldC1zbm1wL2xpYnJhcnkvc25tcF9hbGFybS5oPgojaW5jbHVkZSA8bmV0LXNubXAvbGlicmFyeS9zbm1wX3RyYW5zcG9ydC5oPgojaW5jbHVkZSA8bmV0LXNubXAvbGlicmFyeS9zbm1wX3NlcnZpY2UuaD4KI2luY2x1ZGUgPG5ldC1zbm1wL2xpYnJhcnkvdmFjbS5oPgoKc3RhdGljIHZvaWQgICAgIF9pbml0X3NubXAodm9pZCk7CgojaW5jbHVkZSAiLi4vYWdlbnQvbWliZ3JvdXAvYWdlbnR4L3Byb3RvY29sLmgiCiNpbmNsdWRlIDxuZXQtc25tcC9saWJyYXJ5L3RyYW5zZm9ybV9vaWRzLmg+CiNpZm5kZWYgdGltZXJjbXAKI2RlZmluZQl0aW1lcmNtcCh0dnAsIHV2cCwgY21wKSBcCgkvKiBDU1RZTEVEICovIFwKCSgodHZwKS0+dHZfc2VjIGNtcCAodXZwKS0+dHZfc2VjIHx8IFwKCSgodHZwKS0+dHZfc2VjID09ICh1dnApLT50dl9zZWMgJiYgXAoJLyogQ1NUWUxFRCAqLyBcCgkodHZwKS0+dHZfdXNlYyBjbXAgKHV2cCktPnR2X3VzZWMpKQojZW5kaWYKI2lmbmRlZiB0aW1lcmNsZWFyCiNkZWZpbmUJdGltZXJjbGVhcih0dnApCQkodHZwKS0+dHZfc2VjID0gKHR2cCktPnR2X3VzZWMgPSAwCiNlbmRpZgoKLyoKICogR2xvYmFscy4KICovCiNkZWZpbmUgTUFYX1BBQ0tFVF9MRU5HVEgJKDB4N2ZmZmZmZmYpCiNpZm5kZWYgTkVUU05NUF9TVFJFQU1fUVVFVUVfTEVOCiNkZWZpbmUgTkVUU05NUF9TVFJFQU1fUVVFVUVfTEVOICA1CiNlbmRpZgoKI2lmbmRlZiBCU0Q0XzMKI2RlZmluZSBCU0Q0XzIKI2VuZGlmCgojaWZuZGVmIEZEX1NFVAoKdHlwZWRlZiBsb25nICAgIGZkX21hc2s7CiNkZWZpbmUgTkZEQklUUwkoc2l6ZW9mKGZkX21hc2spICogTkJCWSkgICAgICAgIC8qIGJpdHMgcGVyIG1hc2sgKi8KCiNkZWZpbmUJRkRfU0VUKG4sIHApCSgocCktPmZkc19iaXRzWyhuKS9ORkRCSVRTXSB8PSAoMSA8PCAoKG4pICUgTkZEQklUUykpKQojZGVmaW5lCUZEX0NMUihuLCBwKQkoKHApLT5mZHNfYml0c1sobikvTkZEQklUU10gJj0gfigxIDw8ICgobikgJSBORkRCSVRTKSkpCiNkZWZpbmUJRkRfSVNTRVQobiwgcCkJKChwKS0+ZmRzX2JpdHNbKG4pL05GREJJVFNdICYgKDEgPDwgKChuKSAlIE5GREJJVFMpKSkKI2RlZmluZSBGRF9aRVJPKHApCW1lbXNldCgocCksIDAsIHNpemVvZigqKHApKSkKI2VuZGlmCgpzdGF0aWMgb2lkICAgICAgZGVmYXVsdF9lbnRlcnByaXNlW10gPSB7IDEsIDMsIDYsIDEsIDQsIDEsIDMsIDEsIDEgfTsKLyoKICogZW50ZXJwcmlzZXMuY211LnN5c3RlbXMuY211U05NUCAKICovCgojZGVmaW5lIERFRkFVTFRfQ09NTVVOSVRZICAgInB1YmxpYyIKI2RlZmluZSBERUZBVUxUX1JFVFJJRVMJICAgIDUKI2RlZmluZSBERUZBVUxUX1RJTUVPVVQJICAgIDEwMDAwMDBMCiNkZWZpbmUgREVGQVVMVF9SRU1QT1JUCSAgICBTTk1QX1BPUlQKI2RlZmluZSBERUZBVUxUX0VOVEVSUFJJU0UgIGRlZmF1bHRfZW50ZXJwcmlzZQojZGVmaW5lIERFRkFVTFRfVElNRQkgICAgMAoKLyoKICogZG9uJ3Qgc2V0IGhpZ2hlciB0aGFuIDB4N2ZmZmZmZmYsIGFuZCBJIGRvdWJ0IGl0IHNob3VsZCBiZSB0aGF0IGhpZ2gKICogKiA9IDQgZ2lnIHNubXAgbWVzc2FnZXMgbWF4IAogKi8KI2RlZmluZSBNQVhJTVVNX1BBQ0tFVF9TSVpFIDB4N2ZmZmZmZmYKCi8qCiAqIEludGVybmFsIGluZm9ybWF0aW9uIGFib3V0IHRoZSBzdGF0ZSBvZiB0aGUgc25tcCBzZXNzaW9uLgogKi8Kc3RydWN0IHNubXBfaW50ZXJuYWxfc2Vzc2lvbiB7CiAgICBuZXRzbm1wX3JlcXVlc3RfbGlzdCAqcmVxdWVzdHM7ICAgICAvKiBJbmZvIGFib3V0IG91dHN0YW5kaW5nIHJlcXVlc3RzICovCiAgICBuZXRzbm1wX3JlcXVlc3RfbGlzdCAqcmVxdWVzdHNFbmQ7ICAvKiBwdHIgdG8gZW5kIG9mIGxpc3QgKi8KICAgIGludCAgICAgICAgICAgICAoKmhvb2tfcHJlKSAobmV0c25tcF9zZXNzaW9uICosIG5ldHNubXBfdHJhbnNwb3J0ICosCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZvaWQgKiwgaW50KTsKICAgIGludCAgICAgICAgICAgICAoKmhvb2tfcGFyc2UpIChuZXRzbm1wX3Nlc3Npb24gKiwgbmV0c25tcF9wZHUgKiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1X2NoYXIgKiwgc2l6ZV90KTsKICAgIGludCAgICAgICAgICAgICAoKmhvb2tfcG9zdCkgKG5ldHNubXBfc2Vzc2lvbiAqLCBuZXRzbm1wX3BkdSAqLCBpbnQpOwogICAgaW50ICAgICAgICAgICAgICgqaG9va19idWlsZCkgKG5ldHNubXBfc2Vzc2lvbiAqLCBuZXRzbm1wX3BkdSAqLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVfY2hhciAqLCBzaXplX3QgKik7CiAgICBpbnQgICAgICAgICAgICAgKCpob29rX3JlYWxsb2NfYnVpbGQpIChuZXRzbm1wX3Nlc3Npb24gKiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldHNubXBfcGR1ICosIHVfY2hhciAqKiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNpemVfdCAqLCBzaXplX3QgKik7CiAgICBpbnQgICAgICAgICAgICAgKCpjaGVja19wYWNrZXQpICh1X2NoYXIgKiwgc2l6ZV90KTsKICAgIG5ldHNubXBfcGR1ICAgICooKmhvb2tfY3JlYXRlX3BkdSkgKG5ldHNubXBfdHJhbnNwb3J0ICosCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2b2lkICosIHNpemVfdCk7CgogICAgdV9jaGFyICAgICAgICAgKnBhY2tldDsKICAgIHNpemVfdCAgICAgICAgICBwYWNrZXRfbGVuLCBwYWNrZXRfc2l6ZTsKfTsKCi8qCiAqIFRoZSBsaXN0IG9mIGFjdGl2ZS9vcGVuIHNlc3Npb25zLgogKi8Kc3RydWN0IHNlc3Npb25fbGlzdCB7CiAgICBzdHJ1Y3Qgc2Vzc2lvbl9saXN0ICpuZXh0OwogICAgbmV0c25tcF9zZXNzaW9uICpzZXNzaW9uOwogICAgbmV0c25tcF90cmFuc3BvcnQgKnRyYW5zcG9ydDsKICAgIHN0cnVjdCBzbm1wX2ludGVybmFsX3Nlc3Npb24gKmludGVybmFsOwp9OwoKCgpzdGF0aWMgY29uc3QgY2hhciAqYXBpX2Vycm9yc1stU05NUEVSUl9NQVggKyAxXSA9IHsKICAgICJObyBlcnJvciIsICAgICAgICAgICAgICAgICAvKiBTTk1QRVJSX1NVQ0NFU1MgKi8KICAgICJHZW5lcmljIGVycm9yIiwgICAgICAgICAgICAvKiBTTk1QRVJSX0dFTkVSUiAqLwogICAgIkludmFsaWQgbG9jYWwgcG9ydCIsICAgICAgIC8qIFNOTVBFUlJfQkFEX0xPQ1BPUlQgKi8KICAgICJVbmtub3duIGhvc3QiLCAgICAgICAgICAgICAvKiBTTk1QRVJSX0JBRF9BRERSRVNTICovCiAgICAiVW5rbm93biBzZXNzaW9uIiwgICAgICAgICAgLyogU05NUEVSUl9CQURfU0VTU0lPTiAqLwogICAgIlRvbyBsb25nIiwgICAgICAgICAgICAgICAgIC8qIFNOTVBFUlJfVE9PX0xPTkcgKi8KICAgICJObyBzb2NrZXQiLCAgICAgICAgICAgICAgICAvKiBTTk1QRVJSX05PX1NPQ0tFVCAqLwogICAgIkNhbm5vdCBzZW5kIFYyIFBEVSBvbiBWMSBzZXNzaW9uIiwgLyogU05NUEVSUl9WMl9JTl9WMSAqLwogICAgIkNhbm5vdCBzZW5kIFYxIFBEVSBvbiBWMiBzZXNzaW9uIiwgLyogU05NUEVSUl9WMV9JTl9WMiAqLwogICAgIkJhZCB2YWx1ZSBmb3Igbm9uLXJlcGVhdGVycyIsICAgICAgLyogU05NUEVSUl9CQURfUkVQRUFURVJTICovCiAgICAiQmFkIHZhbHVlIGZvciBtYXgtcmVwZXRpdGlvbnMiLCAgICAvKiBTTk1QRVJSX0JBRF9SRVBFVElUSU9OUyAqLwogICAgIkVycm9yIGJ1aWxkaW5nIEFTTi4xIHJlcHJlc2VudGF0aW9uIiwgICAgICAvKiBTTk1QRVJSX0JBRF9BU04xX0JVSUxEICovCiAgICAiRmFpbHVyZSBpbiBzZW5kdG8iLCAgICAgICAgLyogU05NUEVSUl9CQURfU0VORFRPICovCiAgICAiQmFkIHBhcnNlIG9mIEFTTi4xIHR5cGUiLCAgLyogU05NUEVSUl9CQURfUEFSU0UgKi8KICAgICJCYWQgdmVyc2lvbiBzcGVjaWZpZWQiLCAgICAvKiBTTk1QRVJSX0JBRF9WRVJTSU9OICovCiAgICAiQmFkIHNvdXJjZSBwYXJ0eSBzcGVjaWZpZWQiLCAgICAgICAvKiBTTk1QRVJSX0JBRF9TUkNfUEFSVFkgKi8KICAgICJCYWQgZGVzdGluYXRpb24gcGFydHkgc3BlY2lmaWVkIiwgIC8qIFNOTVBFUlJfQkFEX0RTVF9QQVJUWSAqLwogICAgIkJhZCBjb250ZXh0IHNwZWNpZmllZCIsICAgIC8qIFNOTVBFUlJfQkFEX0NPTlRFWFQgKi8KICAgICJCYWQgY29tbXVuaXR5IHNwZWNpZmllZCIsICAvKiBTTk1QRVJSX0JBRF9DT01NVU5JVFkgKi8KICAgICJDYW5ub3Qgc2VuZCBub0F1dGgvUHJpdiIsICAgICAgIC8qIFNOTVBFUlJfTk9BVVRIX0RFU1BSSVYgKi8KICAgICJCYWQgQUNMIGRlZmluaXRpb24iLCAgICAgICAvKiBTTk1QRVJSX0JBRF9BQ0wgKi8KICAgICJCYWQgUGFydHkgZGVmaW5pdGlvbiIsICAgICAvKiBTTk1QRVJSX0JBRF9QQVJUWSAqLwogICAgIlNlc3Npb24gYWJvcnQgZmFpbHVyZSIsICAgIC8qIFNOTVBFUlJfQUJPUlQgKi8KICAgICJVbmtub3duIFBEVSB0eXBlIiwgICAgICAgICAvKiBTTk1QRVJSX1VOS05PV05fUERVICovCiAgICAiVGltZW91dCIsICAgICAgICAgICAgICAgICAgLyogU05NUEVSUl9USU1FT1VUICovCiAgICAiRmFpbHVyZSBpbiByZWN2ZnJvbSIsICAgICAgLyogU05NUEVSUl9CQURfUkVDVkZST00gKi8KICAgICJVbmFibGUgdG8gZGV0ZXJtaW5lIGNvbnRleHRFbmdpbmVJRCIsICAgICAgLyogU05NUEVSUl9CQURfRU5HX0lEICovCiAgICAiTm8gc2VjdXJpdHlOYW1lIHNwZWNpZmllZCIsICAgICAgICAvKiBTTk1QRVJSX0JBRF9TRUNfTkFNRSAqLwogICAgIlVuYWJsZSB0byBkZXRlcm1pbmUgc2VjdXJpdHlMZXZlbCIsICAgICAgICAvKiBTTk1QRVJSX0JBRF9TRUNfTEVWRUwgICovCiAgICAiQVNOLjEgcGFyc2UgZXJyb3IgaW4gbWVzc2FnZSIsICAgICAvKiBTTk1QRVJSX0FTTl9QQVJTRV9FUlIgKi8KICAgICJVbmtub3duIHNlY3VyaXR5IG1vZGVsIGluIG1lc3NhZ2UiLCAgICAgICAgLyogU05NUEVSUl9VTktOT1dOX1NFQ19NT0RFTCAqLwogICAgIkludmFsaWQgbWVzc2FnZSAoZS5nLiBtc2dGbGFncykiLCAgLyogU05NUEVSUl9JTlZBTElEX01TRyAqLwogICAgIlVua25vd24gZW5naW5lIElEIiwgICAgICAgIC8qIFNOTVBFUlJfVU5LTk9XTl9FTkdfSUQgKi8KICAgICJVbmtub3duIHVzZXIgbmFtZSIsICAgICAgICAvKiBTTk1QRVJSX1VOS05PV05fVVNFUl9OQU1FICovCiAgICAiVW5zdXBwb3J0ZWQgc2VjdXJpdHkgbGV2ZWwiLCAgICAgICAvKiBTTk1QRVJSX1VOU1VQUE9SVEVEX1NFQ19MRVZFTCAqLwogICAgIkF1dGhlbnRpY2F0aW9uIGZhaWx1cmUgKGluY29ycmVjdCBwYXNzd29yZCwgY29tbXVuaXR5IG9yIGtleSkiLCAgICAvKiBTTk1QRVJSX0FVVEhFTlRJQ0FUSU9OX0ZBSUxVUkUgKi8KICAgICJOb3QgaW4gdGltZSB3aW5kb3ciLCAgICAgICAvKiBTTk1QRVJSX05PVF9JTl9USU1FX1dJTkRPVyAqLwogICAgIkRlY3J5cHRpb24gZXJyb3IiLCAgICAgICAgIC8qIFNOTVBFUlJfREVDUllQVElPTl9FUlIgKi8KICAgICJTQ0FQSSBnZW5lcmFsIGZhaWx1cmUiLCAgICAvKiBTTk1QRVJSX1NDX0dFTkVSQUxfRkFJTFVSRSAqLwogICAgIlNDQVBJIHN1Yi1zeXN0ZW0gbm90IGNvbmZpZ3VyZWQiLCAgLyogU05NUEVSUl9TQ19OT1RfQ09ORklHVVJFRCAqLwogICAgIktleSB0b29scyBub3QgYXZhaWxhYmxlIiwgIC8qIFNOTVBFUlJfS1RfTk9UX0FWQUlMQUJMRSAqLwogICAgIlVua25vd24gUmVwb3J0IG1lc3NhZ2UiLCAgIC8qIFNOTVBFUlJfVU5LTk9XTl9SRVBPUlQgKi8KICAgICJVU00gZ2VuZXJpYyBlcnJvciIsICAgICAgICAvKiBTTk1QRVJSX1VTTV9HRU5FUklDRVJST1IgKi8KICAgICJVU00gdW5rbm93biBzZWN1cml0eSBuYW1lIChubyBzdWNoIHVzZXIgZXhpc3RzKSIsICAvKiBTTk1QRVJSX1VTTV9VTktOT1dOU0VDVVJJVFlOQU1FICovCiAgICAiVVNNIHVuc3VwcG9ydGVkIHNlY3VyaXR5IGxldmVsICh0aGlzIHVzZXIgaGFzIG5vdCBiZWVuIGNvbmZpZ3VyZWQgZm9yIHRoYXQgbGV2ZWwgb2Ygc2VjdXJpdHkpIiwgICAgLyogU05NUEVSUl9VU01fVU5TVVBQT1JURURTRUNVUklUWUxFVkVMICovCiAgICAiVVNNIGVuY3J5cHRpb24gZXJyb3IiLCAgICAgLyogU05NUEVSUl9VU01fRU5DUllQVElPTkVSUk9SICovCiAgICAiVVNNIGF1dGhlbnRpY2F0aW9uIGZhaWx1cmUgKGluY29ycmVjdCBwYXNzd29yZCBvciBrZXkpIiwgICAvKiBTTk1QRVJSX1VTTV9BVVRIRU5USUNBVElPTkZBSUxVUkUgKi8KICAgICJVU00gcGFyc2UgZXJyb3IiLCAgICAgICAgICAvKiBTTk1QRVJSX1VTTV9QQVJTRUVSUk9SICovCiAgICAiVVNNIHVua25vd24gZW5naW5lSUQiLCAgICAgLyogU05NUEVSUl9VU01fVU5LTk9XTkVOR0lORUlEICovCiAgICAiVVNNIG5vdCBpbiB0aW1lIHdpbmRvdyIsICAgLyogU05NUEVSUl9VU01fTk9USU5USU1FV0lORE9XICovCiAgICAiVVNNIGRlY3J5cHRpb24gZXJyb3IiLCAgICAgLyogU05NUEVSUl9VU01fREVDUllQVElPTkVSUk9SICovCiAgICAiTUlCIG5vdCBpbml0aWFsaXplZCIsICAgICAgLyogU05NUEVSUl9OT01JQiAqLwogICAgIlZhbHVlIG91dCBvZiByYW5nZSIsICAgICAgIC8qIFNOTVBFUlJfUkFOR0UgKi8KICAgICJTdWItaWQgb3V0IG9mIHJhbmdlIiwgICAgICAvKiBTTk1QRVJSX01BWF9TVUJJRCAqLwogICAgIkJhZCBzdWItaWQgaW4gb2JqZWN0IGlkZW50aWZpZXIiLCAgLyogU05NUEVSUl9CQURfU1VCSUQgKi8KICAgICJPYmplY3QgaWRlbnRpZmllciB0b28gbG9uZyIsICAgICAgIC8qIFNOTVBFUlJfTE9OR19PSUQgKi8KICAgICJCYWQgdmFsdWUgbmFtZSIsICAgICAgICAgICAvKiBTTk1QRVJSX0JBRF9OQU1FICovCiAgICAiQmFkIHZhbHVlIG5vdGF0aW9uIiwgICAgICAgLyogU05NUEVSUl9WQUxVRSAqLwogICAgIlVua25vd24gT2JqZWN0IElkZW50aWZpZXIiLCAgICAgICAgLyogU05NUEVSUl9VTktOT1dOX09CSklEICovCiAgICAiTm8gUERVIGluIHNubXBfc2VuZCIsICAgICAgLyogU05NUEVSUl9OVUxMX1BEVSAqLwogICAgIk1pc3NpbmcgdmFyaWFibGVzIGluIFBEVSIsIC8qIFNOTVBFUlJfTk9fVkFSUyAqLwogICAgIkJhZCB2YXJpYWJsZSB0eXBlIiwgICAgICAgIC8qIFNOTVBFUlJfVkFSX1RZUEUgKi8KICAgICJPdXQgb2YgbWVtb3J5IChtYWxsb2MgZmFpbHVyZSkiLCAgIC8qIFNOTVBFUlJfTUFMTE9DICovCiAgICAiS2VyYmVyb3MgcmVsYXRlZCBlcnJvciIsICAgLyogU05NUEVSUl9LUkI1ICovCiAgICAiUHJvdG9jb2wgZXJyb3IiLAkJLyogU05NUEVSUl9QUk9UT0NPTCAqLwogICAgIk9JRCBub3QgaW5jcmVhc2luZyIsICAgICAgIC8qIFNOTVBFUlJfT0lEX05PTklOQ1JFQVNJTkcgKi8KfTsKCnN0YXRpYyBjb25zdCBjaGFyICpzZWNMZXZlbE5hbWVbXSA9IHsKICAgICJCQURfU0VDX0xFVkVMIiwKICAgICJub0F1dGhOb1ByaXYiLAogICAgImF1dGhOb1ByaXYiLAogICAgImF1dGhQcml2Igp9OwoKLyoKICogTXVsdGlwbGUgdGhyZWFkcyBtYXkgY2hhbmdlcyB0aGVzZSB2YXJpYWJsZXMuCiAqIFN1Z2dlc3QgdXNpbmcgdGhlIFNpbmdsZSBBUEksIHdoaWNoIGRvZXMgbm90IHVzZSBTZXNzaW9ucy4KICoKICogUmVxaWQgbWF5IG5lZWQgdG8gYmUgcHJvdGVjdGVkLiBUaW1lIHdpbGwgdGVsbC4uLgogKgogKi8KLyoKICogTVRDUklUSUNBTF9SRVNPVVJDRQogKi8KLyoKICogdXNlIHRva2VuIGluIGNvbW1lbnRzIHRvIGluZGl2aWR1YWxseSBwcm90ZWN0IHRoZXNlIHJlc291cmNlcyAKICovCnN0cnVjdCBzZXNzaW9uX2xpc3QgKlNlc3Npb25zID0gTlVMTDsgICAvKiBNVF9MSUJfU0VTU0lPTiAqLwpzdGF0aWMgbG9uZyAgICAgUmVxaWQgPSAwOyAgICAgIC8qIE1UX0xJQl9SRVFVRVNUSUQgKi8Kc3RhdGljIGxvbmcgICAgIE1zZ2lkID0gMDsgICAgICAvKiBNVF9MSUJfTUVTU0FHRUlEICovCnN0YXRpYyBsb25nICAgICBTZXNzaWQgPSAwOyAgICAgLyogTVRfTElCX1NFU1NJT05JRCAqLwpzdGF0aWMgbG9uZyAgICAgVHJhbnNpZCA9IDA7ICAgIC8qIE1UX0xJQl9UUkFOU0lEICovCmludCAgICAgICAgICAgICBzbm1wX2Vycm5vID0gMDsKLyoKICogRU5EIE1UQ1JJVElDQUxfUkVTT1VSQ0UKICovCgovKgogKiBnbG9iYWwgZXJyb3IgZGV0YWlsIHN0b3JhZ2UKICovCnN0YXRpYyBjaGFyICAgICBzbm1wX2RldGFpbFsxOTJdOwpzdGF0aWMgaW50ICAgICAgc25tcF9kZXRhaWxfZiA9IDA7CgovKgogKiBQcm90b3R5cGVzLgogKi8KaW50ICAgICAgICAgICAgIHNubXBfYnVpbGQodV9jaGFyICoqIHBrdCwgc2l6ZV90ICogcGt0X2xlbiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgc2l6ZV90ICogb2Zmc2V0LCBuZXRzbm1wX3Nlc3Npb24gKiBwc3MsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldHNubXBfcGR1ICpwZHUpOwpzdGF0aWMgaW50ICAgICAgc25tcF9wYXJzZSh2b2lkICosIG5ldHNubXBfc2Vzc2lvbiAqLCBuZXRzbm1wX3BkdSAqLAogICAgICAgICAgICAgICAgICAgICAgICAgICB1X2NoYXIgKiwgc2l6ZV90KTsKCnN0YXRpYyB2b2lkICAgICBzbm1wdjNfY2FsY19tc2dfZmxhZ3MoaW50LCBpbnQsIHVfY2hhciAqKTsKc3RhdGljIGludCAgICAgIHNubXB2M192ZXJpZnlfbXNnKG5ldHNubXBfcmVxdWVzdF9saXN0ICosIG5ldHNubXBfcGR1ICopOwpzdGF0aWMgaW50ICAgICAgc25tcHYzX2J1aWxkX3Byb2JlX3BkdShuZXRzbm1wX3BkdSAqKik7CnN0YXRpYyBpbnQgICAgICBzbm1wdjNfYnVpbGQodV9jaGFyICoqIHBrdCwgc2l6ZV90ICogcGt0X2xlbiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaXplX3QgKiBvZmZzZXQsIG5ldHNubXBfc2Vzc2lvbiAqIHNlc3Npb24sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV0c25tcF9wZHUgKnBkdSk7CnN0YXRpYyBpbnQgICAgICBzbm1wX3BhcnNlX3ZlcnNpb24odV9jaGFyICosIHNpemVfdCk7CnN0YXRpYyBpbnQgICAgICBzbm1wX3Jlc2VuZF9yZXF1ZXN0KHN0cnVjdCBzZXNzaW9uX2xpc3QgKnNscCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV0c25tcF9yZXF1ZXN0X2xpc3QgKnJwLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgaW5jcl9yZXRyaWVzKTsKc3RhdGljIHZvaWQgICAgIHJlZ2lzdGVyX2RlZmF1bHRfaGFuZGxlcnModm9pZCk7CnN0YXRpYyBzdHJ1Y3Qgc2Vzc2lvbl9saXN0ICpzbm1wX3Nlc3NfY29weShuZXRzbm1wX3Nlc3Npb24gKiBwc3MpOwppbnQgICAgICAgICAgICAgc25tcF9nZXRfZXJybm8odm9pZCk7CnZvaWQgICAgICAgICAgICBzbm1wX3N5bmNoX3Jlc2V0KG5ldHNubXBfc2Vzc2lvbiAqIG5vdHVzZWQpOwp2b2lkICAgICAgICAgICAgc25tcF9zeW5jaF9zZXR1cChuZXRzbm1wX3Nlc3Npb24gKiBub3R1c2VkKTsKCiNpZm5kZWYgSEFWRV9TVFJFUlJPUgpjb25zdCBjaGFyICAgICAqCnN0cmVycm9yKGludCBlcnIpCnsKICAgIGV4dGVybiBjb25zdCBjaGFyICpzeXNfZXJybGlzdFtdOwogICAgZXh0ZXJuIGludCAgICAgIHN5c19uZXJyOwoKICAgIGlmIChlcnIgPCAwIHx8IGVyciA+PSBzeXNfbmVycikKICAgICAgICByZXR1cm4gIlVua25vd24gZXJyb3IiOwogICAgcmV0dXJuIHN5c19lcnJsaXN0W2Vycl07Cn0KI2VuZGlmCgpjb25zdCBjaGFyICoKc25tcF9wZHVfdHlwZShpbnQgdHlwZSkKewogICAgc3RhdGljIGNoYXIgdW5rbm93blsyMF07CiAgICBzd2l0Y2godHlwZSkgewogICAgY2FzZSBTTk1QX01TR19HRVQ6CiAgICAgICAgcmV0dXJuICJHRVQiOwogICAgY2FzZSBTTk1QX01TR19HRVRORVhUOgogICAgICAgIHJldHVybiAiR0VUTkVYVCI7CiAgICBjYXNlIFNOTVBfTVNHX1JFU1BPTlNFOgogICAgICAgIHJldHVybiAiUkVTUE9OU0UiOwogICAgY2FzZSBTTk1QX01TR19TRVQ6CiAgICAgICAgcmV0dXJuICJTRVQiOwogICAgY2FzZSBTTk1QX01TR19HRVRCVUxLOgogICAgICAgIHJldHVybiAiR0VUQlVMSyI7CiAgICBjYXNlIFNOTVBfTVNHX0lORk9STToKICAgICAgICByZXR1cm4gIklORk9STSI7CiAgICBjYXNlIFNOTVBfTVNHX1RSQVAyOgogICAgICAgIHJldHVybiAiVFJBUDIiOwogICAgY2FzZSBTTk1QX01TR19SRVBPUlQ6CiAgICAgICAgcmV0dXJuICJSRVBPUlQiOwogICAgZGVmYXVsdDoKICAgICAgICBzbnByaW50Zih1bmtub3duLCBzaXplb2YodW5rbm93biksICI/MHglMlg/IiwgdHlwZSk7CglyZXR1cm4gdW5rbm93bjsKICAgIH0KfQoKI2RlZmluZSBERUJVR1BSSU5UUERVVFlQRSh0b2tlbiwgdHlwZSkgXAogICAgREVCVUdEVU1QU0VDVElPTih0b2tlbiwgc25tcF9wZHVfdHlwZSh0eXBlKSkKCmxvbmcKc25tcF9nZXRfbmV4dF9yZXFpZCh2b2lkKQp7CiAgICBsb25nICAgICAgICAgICAgcmV0VmFsOwogICAgc25tcF9yZXNfbG9jayhNVF9MSUJSQVJZX0lELCBNVF9MSUJfUkVRVUVTVElEKTsKICAgIHJldFZhbCA9IDEgKyBSZXFpZDsgICAgICAgICAvKk1UQ1JJVElDQUxfUkVTT1VSQ0UgKi8KICAgIGlmICghcmV0VmFsKQogICAgICAgIHJldFZhbCA9IDI7CiAgICBSZXFpZCA9IHJldFZhbDsKICAgIGlmIChuZXRzbm1wX2RzX2dldF9ib29sZWFuKE5FVFNOTVBfRFNfTElCUkFSWV9JRCwgTkVUU05NUF9EU19MSUJfMTZCSVRfSURTKSkKICAgICAgICByZXRWYWwgJj0gMHg3ZmZmOwkvKiBtYXNrIHRvIDE1IGJpdHMgKi8KICAgIGVsc2UKICAgICAgICByZXRWYWwgJj0gMHg3ZmZmZmZmZjsJLyogbWFzayB0byAzMSBiaXRzICovCgogICAgaWYgKCFyZXRWYWwpIHsKICAgICAgICBSZXFpZCA9IHJldFZhbCA9IDI7CiAgICB9CiAgICBzbm1wX3Jlc191bmxvY2soTVRfTElCUkFSWV9JRCwgTVRfTElCX1JFUVVFU1RJRCk7CiAgICByZXR1cm4gcmV0VmFsOwp9Cgpsb25nCnNubXBfZ2V0X25leHRfbXNnaWQodm9pZCkKewogICAgbG9uZyAgICAgICAgICAgIHJldFZhbDsKICAgIHNubXBfcmVzX2xvY2soTVRfTElCUkFSWV9JRCwgTVRfTElCX01FU1NBR0VJRCk7CiAgICByZXRWYWwgPSAxICsgTXNnaWQ7ICAgICAgICAgLypNVENSSVRJQ0FMX1JFU09VUkNFICovCiAgICBpZiAoIXJldFZhbCkKICAgICAgICByZXRWYWwgPSAyOwogICAgTXNnaWQgPSByZXRWYWw7CiAgICBpZiAobmV0c25tcF9kc19nZXRfYm9vbGVhbihORVRTTk1QX0RTX0xJQlJBUllfSUQsIE5FVFNOTVBfRFNfTElCXzE2QklUX0lEUykpCiAgICAgICAgcmV0VmFsICY9IDB4N2ZmZjsJLyogbWFzayB0byAxNSBiaXRzICovCiAgICBlbHNlCiAgICAgICAgcmV0VmFsICY9IDB4N2ZmZmZmZmY7CS8qIG1hc2sgdG8gMzEgYml0cyAqLwoKICAgIGlmICghcmV0VmFsKSB7CiAgICAgICAgTXNnaWQgPSByZXRWYWwgPSAyOwogICAgfQogICAgc25tcF9yZXNfdW5sb2NrKE1UX0xJQlJBUllfSUQsIE1UX0xJQl9NRVNTQUdFSUQpOwogICAgcmV0dXJuIHJldFZhbDsKfQoKbG9uZwpzbm1wX2dldF9uZXh0X3Nlc3NpZCh2b2lkKQp7CiAgICBsb25nICAgICAgICAgICAgcmV0VmFsOwogICAgc25tcF9yZXNfbG9jayhNVF9MSUJSQVJZX0lELCBNVF9MSUJfU0VTU0lPTklEKTsKICAgIHJldFZhbCA9IDEgKyBTZXNzaWQ7ICAgICAgICAvKk1UQ1JJVElDQUxfUkVTT1VSQ0UgKi8KICAgIGlmICghcmV0VmFsKQogICAgICAgIHJldFZhbCA9IDI7CiAgICBTZXNzaWQgPSByZXRWYWw7CiAgICBpZiAobmV0c25tcF9kc19nZXRfYm9vbGVhbihORVRTTk1QX0RTX0xJQlJBUllfSUQsIE5FVFNOTVBfRFNfTElCXzE2QklUX0lEUykpCiAgICAgICAgcmV0VmFsICY9IDB4N2ZmZjsJLyogbWFzayB0byAxNSBiaXRzICovCiAgICBlbHNlCiAgICAgICAgcmV0VmFsICY9IDB4N2ZmZmZmZmY7CS8qIG1hc2sgdG8gMzEgYml0cyAqLwoKICAgIGlmICghcmV0VmFsKSB7CiAgICAgICAgU2Vzc2lkID0gcmV0VmFsID0gMjsKICAgIH0KICAgIHNubXBfcmVzX3VubG9jayhNVF9MSUJSQVJZX0lELCBNVF9MSUJfU0VTU0lPTklEKTsKICAgIHJldHVybiByZXRWYWw7Cn0KCmxvbmcKc25tcF9nZXRfbmV4dF90cmFuc2lkKHZvaWQpCnsKICAgIGxvbmcgICAgICAgICAgICByZXRWYWw7CiAgICBzbm1wX3Jlc19sb2NrKE1UX0xJQlJBUllfSUQsIE1UX0xJQl9UUkFOU0lEKTsKICAgIHJldFZhbCA9IDEgKyBUcmFuc2lkOyAgICAgICAvKk1UQ1JJVElDQUxfUkVTT1VSQ0UgKi8KICAgIGlmICghcmV0VmFsKQogICAgICAgIHJldFZhbCA9IDI7CiAgICBUcmFuc2lkID0gcmV0VmFsOwogICAgaWYgKG5ldHNubXBfZHNfZ2V0X2Jvb2xlYW4oTkVUU05NUF9EU19MSUJSQVJZX0lELCBORVRTTk1QX0RTX0xJQl8xNkJJVF9JRFMpKQogICAgICAgIHJldFZhbCAmPSAweDdmZmY7CS8qIG1hc2sgdG8gMTUgYml0cyAqLwogICAgZWxzZQogICAgICAgIHJldFZhbCAmPSAweDdmZmZmZmZmOwkvKiBtYXNrIHRvIDMxIGJpdHMgKi8KCiAgICBpZiAoIXJldFZhbCkgewogICAgICAgIFRyYW5zaWQgPSByZXRWYWwgPSAyOwogICAgfQogICAgc25tcF9yZXNfdW5sb2NrKE1UX0xJQlJBUllfSUQsIE1UX0xJQl9UUkFOU0lEKTsKICAgIHJldHVybiByZXRWYWw7Cn0KCnZvaWQKc25tcF9wZXJyb3IoY29uc3QgY2hhciAqcHJvZ19zdHJpbmcpCnsKICAgIGNvbnN0IGNoYXIgICAgICpzdHI7CiAgICBpbnQgICAgICAgICAgICAgeGVycjsKICAgIHhlcnIgPSBzbm1wX2Vycm5vOyAgICAgICAgICAvKk1UQ1JJVElDQUxfUkVTT1VSQ0UgKi8KICAgIHN0ciA9IHNubXBfYXBpX2VycnN0cmluZyh4ZXJyKTsKICAgIHNubXBfbG9nKExPR19FUlIsICIlczogJXNcbiIsIHByb2dfc3RyaW5nLCBzdHIpOwp9Cgp2b2lkCnNubXBfc2V0X2RldGFpbChjb25zdCBjaGFyICpkZXRhaWxfc3RyaW5nKQp7CiAgICBpZiAoZGV0YWlsX3N0cmluZyAhPSBOVUxMKSB7CiAgICAgICAgc3RybGNweSgoY2hhciAqKSBzbm1wX2RldGFpbCwgZGV0YWlsX3N0cmluZywgc2l6ZW9mKHNubXBfZGV0YWlsKSk7CiAgICAgICAgc25tcF9kZXRhaWxfZiA9IDE7CiAgICB9Cn0KCi8qCiAqIHJldHVybnMgcG9pbnRlciB0byBzdGF0aWMgZGF0YSAKICovCi8qCiAqIHJlc3VsdHMgbm90IGd1YXJhbnRlZWQgaW4gbXVsdGktdGhyZWFkZWQgdXNlIAogKi8KY29uc3QgY2hhciAgICAgKgpzbm1wX2FwaV9lcnJzdHJpbmcoaW50IHNubXBfZXJybnVtYmVyKQp7CiAgICBjb25zdCBjaGFyICAgICAqbXNnID0gIiI7CiAgICBzdGF0aWMgY2hhciAgICAgbXNnX2J1ZltTUFJJTlRfTUFYX0xFTl07CgogICAgaWYgKHNubXBfZXJybnVtYmVyID49IFNOTVBFUlJfTUFYICYmIHNubXBfZXJybnVtYmVyIDw9IFNOTVBFUlJfR0VORVJSKSB7CiAgICAgICAgbXNnID0gYXBpX2Vycm9yc1stc25tcF9lcnJudW1iZXJdOwogICAgfSBlbHNlIGlmIChzbm1wX2Vycm51bWJlciAhPSBTTk1QRVJSX1NVQ0NFU1MpIHsKICAgICAgICBtc2cgPSBOVUxMOwogICAgfQogICAgaWYgKCFtc2cpIHsKCXNucHJpbnRmKG1zZ19idWYsIHNpemVvZihtc2dfYnVmKSwgIlVua25vd24gZXJyb3I6ICVkIiwgc25tcF9lcnJudW1iZXIpOwogICAgICAgIG1zZ19idWZbc2l6ZW9mKG1zZ19idWYpLTFdID0gJ1wwJzsKICAgIH0gZWxzZSBpZiAoc25tcF9kZXRhaWxfZikgewogICAgICAgIHNucHJpbnRmKG1zZ19idWYsIHNpemVvZihtc2dfYnVmKSwgIiVzICglcykiLCBtc2csIHNubXBfZGV0YWlsKTsKICAgICAgICBtc2dfYnVmW3NpemVvZihtc2dfYnVmKS0xXSA9ICdcMCc7CiAgICAgICAgc25tcF9kZXRhaWxfZiA9IDA7CiAgICB9IGVsc2UgewogICAgICAgIHN0cmxjcHkobXNnX2J1ZiwgbXNnLCBzaXplb2YobXNnX2J1ZikpOwogICAgfQoKICAgIHJldHVybiAobXNnX2J1Zik7Cn0KCi8qCiAqIHNubXBfZXJyb3IgLSByZXR1cm4gZXJyb3IgZGF0YQogKiBJbnB1dHMgOiAgYWRkcmVzcyBvZiBlcnJubywgYWRkcmVzcyBvZiBzbm1wX2Vycm5vLCBhZGRyZXNzIG9mIHN0cmluZwogKiBDYWxsZXIgbXVzdCBmcmVlIHRoZSBzdHJpbmcgcmV0dXJuZWQgYWZ0ZXIgdXNlLgogKi8Kdm9pZApzbm1wX2Vycm9yKG5ldHNubXBfc2Vzc2lvbiAqIHBzZXNzLAogICAgICAgICAgIGludCAqcF9lcnJubywgaW50ICpwX3NubXBfZXJybm8sIGNoYXIgKipwX3N0cikKewogICAgY2hhciAgICAgICAgICAgIGJ1ZltTUFJJTlRfTUFYX0xFTl07CiAgICBpbnQgICAgICAgICAgICAgc25tcF9lcnJudW1iZXI7CgogICAgaWYgKHBfZXJybm8pCiAgICAgICAgKnBfZXJybm8gPSBwc2Vzcy0+c19lcnJubzsKICAgIGlmIChwX3NubXBfZXJybm8pCiAgICAgICAgKnBfc25tcF9lcnJubyA9IHBzZXNzLT5zX3NubXBfZXJybm87CiAgICBpZiAocF9zdHIgPT0gTlVMTCkKICAgICAgICByZXR1cm47CgogICAgc3RyY3B5KGJ1ZiwgIiIpOwogICAgc25tcF9lcnJudW1iZXIgPSBwc2Vzcy0+c19zbm1wX2Vycm5vOwogICAgaWYgKHNubXBfZXJybnVtYmVyID49IFNOTVBFUlJfTUFYICYmIHNubXBfZXJybnVtYmVyIDw9IFNOTVBFUlJfR0VORVJSKSB7CglpZiAoc25tcF9kZXRhaWxfZikgewogICAgICAgICAgICBzbnByaW50ZihidWYsIHNpemVvZihidWYpLCAiJXMgKCVzKSIsIGFwaV9lcnJvcnNbLXNubXBfZXJybnVtYmVyXSwKCQkgICAgc25tcF9kZXRhaWwpOwogICAgICAgICAgICBidWZbc2l6ZW9mKGJ1ZiktMV0gPSAnXDAnOwoJICAgIHNubXBfZGV0YWlsX2YgPSAwOwoJfQoJZWxzZQoJICAgIHN0cmxjcHkoYnVmLCBhcGlfZXJyb3JzWy1zbm1wX2Vycm51bWJlcl0sIHNpemVvZihidWYpKTsKICAgIH0gZWxzZSB7CiAgICAgICAgaWYgKHNubXBfZXJybnVtYmVyKSB7CiAgICAgICAgICAgIHNucHJpbnRmKGJ1Ziwgc2l6ZW9mKGJ1ZiksICJVbmtub3duIEVycm9yICVkIiwgc25tcF9lcnJudW1iZXIpOwogICAgICAgICAgICBidWZbc2l6ZW9mKGJ1ZiktMV0gPSAnXDAnOwogICAgICAgIH0KICAgIH0KCiAgICAvKgogICAgICogYXBwZW5kIGEgdXNlZnVsIHN5c3RlbSBlcnJubyBpbnRlcnByZXRhdGlvbi4gCiAgICAgKi8KICAgIGlmIChwc2Vzcy0+c19lcnJubykgewogICAgICAgIGNvbnN0IGNoYXIqIGVycm9yID0gc3RyZXJyb3IocHNlc3MtPnNfZXJybm8pOwogICAgICAgIGlmKGVycm9yID09IE5VTEwpCiAgICAgICAgICAgIGVycm9yID0gIlVua25vd24gRXJyb3IiOwogICAgICAgIHNucHJpbnRmICgmYnVmW3N0cmxlbihidWYpXSwgc2l6ZW9mKGJ1Ziktc3RybGVuKGJ1ZiksCiAgICAgICAgICAgICAgICAgIiAoJXMpIiwgZXJyb3IpOwogICAgfQogICAgYnVmW3NpemVvZihidWYpLTFdID0gJ1wwJzsKICAgICpwX3N0ciA9IHN0cmR1cChidWYpOwp9CgovKgogKiBzbm1wX3Nlc3NfZXJyb3IgLSBzYW1lIGFzIHNubXBfZXJyb3IgZm9yIHNpbmdsZSBzZXNzaW9uIEFQSSB1c2UuCiAqLwp2b2lkCnNubXBfc2Vzc19lcnJvcih2b2lkICpzZXNzcCwgaW50ICpwX2Vycm5vLCBpbnQgKnBfc25tcF9lcnJubywgY2hhciAqKnBfc3RyKQp7CiAgICBzdHJ1Y3Qgc2Vzc2lvbl9saXN0ICpzbHAgPSAoc3RydWN0IHNlc3Npb25fbGlzdCAqKSBzZXNzcDsKCiAgICBpZiAoKHNscCkgJiYgKHNscC0+c2Vzc2lvbikpCiAgICAgICAgc25tcF9lcnJvcihzbHAtPnNlc3Npb24sIHBfZXJybm8sIHBfc25tcF9lcnJubywgcF9zdHIpOwp9CgovKgogKiBuZXRzbm1wX3Nlc3NfbG9nX2Vycm9yKCk6IHByaW50IGEgZXJyb3Igc3RvcmVkIGluIGEgc2Vzc2lvbiBwb2ludGVyIAogKi8Kdm9pZApuZXRzbm1wX3Nlc3NfbG9nX2Vycm9yKGludCBwcmlvcml0eSwKICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBjaGFyICpwcm9nX3N0cmluZywgbmV0c25tcF9zZXNzaW9uICogc3MpCnsKICAgIGNoYXIgICAgICAgICAgICplcnI7CiAgICBzbm1wX2Vycm9yKHNzLCBOVUxMLCBOVUxMLCAmZXJyKTsKICAgIHNubXBfbG9nKHByaW9yaXR5LCAiJXM6ICVzXG4iLCBwcm9nX3N0cmluZywgZXJyKTsKICAgIFNOTVBfRlJFRShlcnIpOwp9CgovKgogKiBzbm1wX3Nlc3NfcGVycm9yKCk6IHByaW50IGEgZXJyb3Igc3RvcmVkIGluIGEgc2Vzc2lvbiBwb2ludGVyIAogKi8Kdm9pZApzbm1wX3Nlc3NfcGVycm9yKGNvbnN0IGNoYXIgKnByb2dfc3RyaW5nLCBuZXRzbm1wX3Nlc3Npb24gKiBzcykKewogICAgbmV0c25tcF9zZXNzX2xvZ19lcnJvcihMT0dfRVJSLCBwcm9nX3N0cmluZywgc3MpOwp9CgoKCi8qCiAqIFByaW1vcmRpYWwgU05NUCBsaWJyYXJ5IGluaXRpYWxpemF0aW9uLgogKiBJbml0aWFsaXplcyBtdXRleCBsb2Nrcy4KICogSW52b2tlcyBtaW5pbXVtIHJlcXVpcmVkIGluaXRpYWxpemF0aW9uIGZvciBkaXNwbGF5aW5nIE1JQiBvYmplY3RzLgogKiBHZXRzIGluaXRpYWwgcmVxdWVzdCBJRCBmb3IgYWxsIHRyYW5zYWN0aW9ucywKICogYW5kIGZpbmRzIHdoaWNoIHBvcnQgU05NUCBvdmVyIFVEUCB1c2VzLgogKiBTTk1QIG92ZXIgQXBwbGVUYWxrIGlzIG5vdCBjdXJyZW50bHkgc3VwcG9ydGVkLgogKgogKiBXYXJuaW5nOiBubyBkZWJ1ZyBtZXNzYWdlcyBoZXJlLgogKi8Kc3RhdGljIGNoYXIgX2luaXRfc25tcF9pbml0X2RvbmUgPSAwOwpzdGF0aWMgdm9pZApfaW5pdF9zbm1wKHZvaWQpCnsKCiAgICBzdHJ1Y3QgdGltZXZhbCAgdHY7CiAgICBsb25nICAgICAgICAgICAgdG1wUmVxaWQsIHRtcE1zZ2lkOwoKICAgIGlmIChfaW5pdF9zbm1wX2luaXRfZG9uZSkKICAgICAgICByZXR1cm47CiAgICBfaW5pdF9zbm1wX2luaXRfZG9uZSA9IDE7CiAgICBSZXFpZCA9IDE7CgogICAgc25tcF9yZXNfaW5pdCgpOyAgICAgICAgICAgIC8qIGluaXRpYWxpemUgdGhlIG10IGxvY2tpbmcgc3RydWN0dXJlcyAqLwojaWZuZGVmIE5FVFNOTVBfRElTQUJMRV9NSUJfTE9BRElORwogICAgbmV0c25tcF9pbml0X21pYl9pbnRlcm5hbHMoKTsKI2VuZGlmIC8qIE5FVFNOTVBfRElTQUJMRV9NSUJfTE9BRElORyAqLwogICAgbmV0c25tcF90ZG9tYWluX2luaXQoKTsKCiAgICBnZXR0aW1lb2ZkYXkoJnR2LCAoc3RydWN0IHRpbWV6b25lICopIDApOwogICAgLyoKICAgICAqIE5vdyA9IHR2OwogICAgICovCgogICAgLyoKICAgICAqIGdldCBwc2V1ZG8tcmFuZG9tIHZhbHVlcyBmb3IgcmVxdWVzdCBJRCBhbmQgbWVzc2FnZSBJRCAKICAgICAqLwogICAgLyoKICAgICAqIGRvbid0IGFsbG93IHplcm8gdmFsdWUgdG8gcmVwZWF0IGluaXQgCiAgICAgKi8KI2lmZGVmIFNWUjQKICAgIHNyYW5kNDgodHYudHZfc2VjIF4gdHYudHZfdXNlYyk7CiAgICB0bXBSZXFpZCA9IGxyYW5kNDgoKTsKICAgIHRtcE1zZ2lkID0gbHJhbmQ0OCgpOwojZWxzZQogICAgc3JhbmRvbSh0di50dl9zZWMgXiB0di50dl91c2VjKTsKICAgIHRtcFJlcWlkID0gcmFuZG9tKCk7CiAgICB0bXBNc2dpZCA9IHJhbmRvbSgpOwojZW5kaWYKCiAgICBpZiAodG1wUmVxaWQgPT0gMCkKICAgICAgICB0bXBSZXFpZCA9IDE7CiAgICBpZiAodG1wTXNnaWQgPT0gMCkKICAgICAgICB0bXBNc2dpZCA9IDE7CiAgICBSZXFpZCA9IHRtcFJlcWlkOwogICAgTXNnaWQgPSB0bXBNc2dpZDsKCiAgICBuZXRzbm1wX3JlZ2lzdGVyX2RlZmF1bHRfZG9tYWluKCJzbm1wIiwgInVkcCB1ZHA2Iik7CiAgICBuZXRzbm1wX3JlZ2lzdGVyX2RlZmF1bHRfZG9tYWluKCJzbm1wdHJhcCIsICJ1ZHAgdWRwNiIpOwoKICAgIG5ldHNubXBfcmVnaXN0ZXJfZGVmYXVsdF90YXJnZXQoInNubXAiLCAidWRwIiwgIjoxNjEiKTsKICAgIG5ldHNubXBfcmVnaXN0ZXJfZGVmYXVsdF90YXJnZXQoInNubXAiLCAidGNwIiwgIjoxNjEiKTsKICAgIG5ldHNubXBfcmVnaXN0ZXJfZGVmYXVsdF90YXJnZXQoInNubXAiLCAidWRwNiIsICI6MTYxIik7CiAgICBuZXRzbm1wX3JlZ2lzdGVyX2RlZmF1bHRfdGFyZ2V0KCJzbm1wIiwgInRjcDYiLCAiOjE2MSIpOwogICAgbmV0c25tcF9yZWdpc3Rlcl9kZWZhdWx0X3RhcmdldCgic25tcCIsICJpcHgiLCAiLzM2ODc5Iik7CiAgICBuZXRzbm1wX3JlZ2lzdGVyX2RlZmF1bHRfdGFyZ2V0KCJzbm1wdHJhcCIsICJ1ZHAiLCAiOjE2MiIpOwogICAgbmV0c25tcF9yZWdpc3Rlcl9kZWZhdWx0X3RhcmdldCgic25tcHRyYXAiLCAidGNwIiwgIjoxNjIiKTsKICAgIG5ldHNubXBfcmVnaXN0ZXJfZGVmYXVsdF90YXJnZXQoInNubXB0cmFwIiwgInVkcDYiLCAiOjE2MiIpOwogICAgbmV0c25tcF9yZWdpc3Rlcl9kZWZhdWx0X3RhcmdldCgic25tcHRyYXAiLCAidGNwNiIsICI6MTYyIik7CiAgICBuZXRzbm1wX3JlZ2lzdGVyX2RlZmF1bHRfdGFyZ2V0KCJzbm1wdHJhcCIsICJpcHgiLCAiLzM2ODgwIik7CgogICAgbmV0c25tcF9kc19zZXRfaW50KE5FVFNOTVBfRFNfTElCUkFSWV9JRCwgCiAgICAgICAgICAgICAgICAgICAgICAgTkVUU05NUF9EU19MSUJfSEVYX09VVFBVVF9MRU5HVEgsIDE2KTsKCiNpZmRlZiBORVRTTk1QX1VTRV9SRVZFUlNFX0FTTkVOQ09ESU5HCiAgICBuZXRzbm1wX2RzX3NldF9ib29sZWFuKE5FVFNOTVBfRFNfTElCUkFSWV9JRCwgCgkJCSAgIE5FVFNOTVBfRFNfTElCX1JFVkVSU0VfRU5DT0RFLAoJCQkgICBORVRTTk1QX0RFRkFVTFRfQVNORU5DT0RJTkdfRElSRUNUSU9OKTsKI2VuZGlmCn0KCi8qCiAqIEluaXRpYWxpemVzIHRoZSBzZXNzaW9uIHN0cnVjdHVyZS4KICogTWF5IHBlcmZvcm0gb25lIHRpbWUgbWluaW1hbCBsaWJyYXJ5IGluaXRpYWxpemF0aW9uLgogKiBObyBNSUIgZmlsZSBwcm9jZXNzaW5nIGlzIGRvbmUgdmlhIHRoaXMgY2FsbC4KICovCnZvaWQKc25tcF9zZXNzX2luaXQobmV0c25tcF9zZXNzaW9uICogc2Vzc2lvbikKewogICAgX2luaXRfc25tcCgpOwoKICAgIC8qCiAgICAgKiBpbml0aWFsaXplIHNlc3Npb24gdG8gZGVmYXVsdCB2YWx1ZXMgCiAgICAgKi8KCiAgICBtZW1zZXQoc2Vzc2lvbiwgMCwgc2l6ZW9mKG5ldHNubXBfc2Vzc2lvbikpOwogICAgc2Vzc2lvbi0+cmVtb3RlX3BvcnQgPSBTTk1QX0RFRkFVTFRfUkVNUE9SVDsKICAgIHNlc3Npb24tPnRpbWVvdXQgPSBTTk1QX0RFRkFVTFRfVElNRU9VVDsKICAgIHNlc3Npb24tPnJldHJpZXMgPSBTTk1QX0RFRkFVTFRfUkVUUklFUzsKICAgIHNlc3Npb24tPnZlcnNpb24gPSBTTk1QX0RFRkFVTFRfVkVSU0lPTjsKICAgIHNlc3Npb24tPnNlY3VyaXR5TW9kZWwgPSBTTk1QX0RFRkFVTFRfU0VDTU9ERUw7CiAgICBzZXNzaW9uLT5yY3ZNc2dNYXhTaXplID0gU05NUF9NQVhfTVNHX1NJWkU7CiAgICBzZXNzaW9uLT5mbGFncyB8PSBTTk1QX0ZMQUdTX0RPTlRfUFJPQkU7Cn0KCgpzdGF0aWMgdm9pZApyZWdpc3Rlcl9kZWZhdWx0X2hhbmRsZXJzKHZvaWQpCnsKICAgIG5ldHNubXBfZHNfcmVnaXN0ZXJfY29uZmlnKEFTTl9CT09MRUFOLCAic25tcCIsICJkdW1wUGFja2V0IiwKCQkgICAgICBORVRTTk1QX0RTX0xJQlJBUllfSUQsIE5FVFNOTVBfRFNfTElCX0RVTVBfUEFDS0VUKTsKICAgIG5ldHNubXBfZHNfcmVnaXN0ZXJfY29uZmlnKEFTTl9CT09MRUFOLCAic25tcCIsICJyZXZlcnNlRW5jb2RlQkVSIiwKCQkgICAgICBORVRTTk1QX0RTX0xJQlJBUllfSUQsIE5FVFNOTVBfRFNfTElCX1JFVkVSU0VfRU5DT0RFKTsKICAgIG5ldHNubXBfZHNfcmVnaXN0ZXJfY29uZmlnKEFTTl9JTlRFR0VSLCAic25tcCIsICJkZWZhdWx0UG9ydCIsCgkJICAgICAgTkVUU05NUF9EU19MSUJSQVJZX0lELCBORVRTTk1QX0RTX0xJQl9ERUZBVUxUX1BPUlQpOwojaWYgIWRlZmluZWQoTkVUU05NUF9ESVNBQkxFX1NOTVBWMSkgfHwgIWRlZmluZWQoTkVUU05NUF9ESVNBQkxFX1NOTVBWMkMpCiAgICBuZXRzbm1wX2RzX3JlZ2lzdGVyX2NvbmZpZyhBU05fT0NURVRfU1RSLCAic25tcCIsICJkZWZDb21tdW5pdHkiLAogICAgICAgICAgICAgICAgICAgICAgTkVUU05NUF9EU19MSUJSQVJZX0lELCBORVRTTk1QX0RTX0xJQl9DT01NVU5JVFkpOwojZW5kaWYKICAgIG5ldHNubXBfZHNfcmVnaXN0ZXJfcHJlbWliKEFTTl9CT09MRUFOLCAic25tcCIsICJub1Rva2VuV2FybmluZ3MiLAogICAgICAgICAgICAgICAgICAgICAgTkVUU05NUF9EU19MSUJSQVJZX0lELCBORVRTTk1QX0RTX0xJQl9OT19UT0tFTl9XQVJOSU5HUyk7CiAgICBuZXRzbm1wX2RzX3JlZ2lzdGVyX2NvbmZpZyhBU05fQk9PTEVBTiwgInNubXAiLCAibm9SYW5nZUNoZWNrIiwKCQkgICAgICBORVRTTk1QX0RTX0xJQlJBUllfSUQsIE5FVFNOTVBfRFNfTElCX0RPTlRfQ0hFQ0tfUkFOR0UpOwogICAgbmV0c25tcF9kc19yZWdpc3Rlcl9wcmVtaWIoQVNOX09DVEVUX1NUUiwgInNubXAiLCAicGVyc2lzdGVudERpciIsCgkgICAgICAgICAgICAgIE5FVFNOTVBfRFNfTElCUkFSWV9JRCwgTkVUU05NUF9EU19MSUJfUEVSU0lTVEVOVF9ESVIpOwogICAgbmV0c25tcF9kc19yZWdpc3Rlcl9jb25maWcoQVNOX09DVEVUX1NUUiwgInNubXAiLCAidGVtcEZpbGVQYXR0ZXJuIiwKCSAgICAgICAgICAgICAgTkVUU05NUF9EU19MSUJSQVJZX0lELCBORVRTTk1QX0RTX0xJQl9URU1QX0ZJTEVfUEFUVEVSTik7CiAgICBuZXRzbm1wX2RzX3JlZ2lzdGVyX2NvbmZpZyhBU05fQk9PTEVBTiwgInNubXAiLCAibm9EaXNwbGF5SGludCIsCgkgICAgICAgICAgICAgIE5FVFNOTVBfRFNfTElCUkFSWV9JRCwgTkVUU05NUF9EU19MSUJfTk9fRElTUExBWV9ISU5UKTsKICAgIG5ldHNubXBfZHNfcmVnaXN0ZXJfY29uZmlnKEFTTl9CT09MRUFOLCAic25tcCIsICIxNmJpdElEcyIsCgkgICAgICAgICAgICAgIE5FVFNOTVBfRFNfTElCUkFSWV9JRCwgTkVUU05NUF9EU19MSUJfMTZCSVRfSURTKTsKICAgIG5ldHNubXBfZHNfcmVnaXN0ZXJfcHJlbWliKEFTTl9PQ1RFVF9TVFIsICJzbm1wIiwgImNsaWVudGFkZHIiLAogICAgICAgICAgICAgICAgICAgICAgTkVUU05NUF9EU19MSUJSQVJZX0lELCBORVRTTk1QX0RTX0xJQl9DTElFTlRfQUREUik7CiAgICBuZXRzbm1wX2RzX3JlZ2lzdGVyX2NvbmZpZyhBU05fSU5URUdFUiwgInNubXAiLCAic2VydmVyU2VuZEJ1ZiIsCgkJICAgICAgTkVUU05NUF9EU19MSUJSQVJZX0lELCBORVRTTk1QX0RTX0xJQl9TRVJWRVJTRU5EQlVGKTsKICAgIG5ldHNubXBfZHNfcmVnaXN0ZXJfY29uZmlnKEFTTl9JTlRFR0VSLCAic25tcCIsICJzZXJ2ZXJSZWN2QnVmIiwKCQkgICAgICBORVRTTk1QX0RTX0xJQlJBUllfSUQsIE5FVFNOTVBfRFNfTElCX1NFUlZFUlJFQ1ZCVUYpOwogICAgbmV0c25tcF9kc19yZWdpc3Rlcl9jb25maWcoQVNOX0lOVEVHRVIsICJzbm1wIiwgImNsaWVudFNlbmRCdWYiLAoJCSAgICAgIE5FVFNOTVBfRFNfTElCUkFSWV9JRCwgTkVUU05NUF9EU19MSUJfQ0xJRU5UU0VOREJVRik7CiAgICBuZXRzbm1wX2RzX3JlZ2lzdGVyX2NvbmZpZyhBU05fSU5URUdFUiwgInNubXAiLCAiY2xpZW50UmVjdkJ1ZiIsCgkJICAgICAgTkVUU05NUF9EU19MSUJSQVJZX0lELCBORVRTTk1QX0RTX0xJQl9DTElFTlRSRUNWQlVGKTsKICAgIG5ldHNubXBfZHNfcmVnaXN0ZXJfY29uZmlnKEFTTl9CT09MRUFOLCAic25tcCIsICJub1BlcnNpc3RlbnRMb2FkIiwKCQkgICAgICBORVRTTk1QX0RTX0xJQlJBUllfSUQsIE5FVFNOTVBfRFNfTElCX0RJU0FCTEVfUEVSU0lTVEVOVF9MT0FEKTsKICAgIG5ldHNubXBfZHNfcmVnaXN0ZXJfY29uZmlnKEFTTl9CT09MRUFOLCAic25tcCIsICJub1BlcnNpc3RlbnRTYXZlIiwKCQkgICAgICBORVRTTk1QX0RTX0xJQlJBUllfSUQsIE5FVFNOTVBfRFNfTElCX0RJU0FCTEVfUEVSU0lTVEVOVF9TQVZFKTsKICAgIG5ldHNubXBfcmVnaXN0ZXJfc2VydmljZV9oYW5kbGVycygpOwp9CgpzdGF0aWMgaW50IGluaXRfc25tcF9pbml0X2RvbmUgPSAwOyAvKiBUbyBwcmV2ZW50IGRvdWJsZSBpbml0J3MuICovCi8qKgogKiBDYWxscyB0aGUgZnVuY3Rpb25zIHRvIGRvIGNvbmZpZyBmaWxlIGxvYWRpbmcgYW5kICBtaWIgbW9kdWxlIHBhcnNpbmcKICogaW4gdGhlIGNvcnJlY3Qgb3JkZXIuCiAqCiAqIEBwYXJhbSB0eXBlIGxhYmVsIGZvciB0aGUgY29uZmlnIGZpbGUgInR5cGUiCiAqCiAqIEByZXR1cm4gdm9pZAogKgogKiBAc2VlIGluaXRfYWdlbnQKICovCnZvaWQKaW5pdF9zbm1wKGNvbnN0IGNoYXIgKnR5cGUpCnsKICAgIGlmIChpbml0X3NubXBfaW5pdF9kb25lKSB7CiAgICAgICAgcmV0dXJuOwogICAgfQoKICAgIGluaXRfc25tcF9pbml0X2RvbmUgPSAxOwoKICAgIC8qCiAgICAgKiBtYWtlIHRoZSB0eXBlIGF2YWlsYWJsZSBldmVyeXdoZXJlIGVsc2UgCiAgICAgKi8KICAgIGlmICh0eXBlICYmICFuZXRzbm1wX2RzX2dldF9zdHJpbmcoTkVUU05NUF9EU19MSUJSQVJZX0lELCAKCQkJCSAgICAgICBORVRTTk1QX0RTX0xJQl9BUFBUWVBFKSkgewogICAgICAgIG5ldHNubXBfZHNfc2V0X3N0cmluZyhORVRTTk1QX0RTX0xJQlJBUllfSUQsIAoJCQkgICAgICBORVRTTk1QX0RTX0xJQl9BUFBUWVBFLCB0eXBlKTsKICAgIH0KCiAgICBfaW5pdF9zbm1wKCk7CgogICAgLyoKICAgICAqIHNldCBvdXIgY3VycmVudCBsb2NhbGUgcHJvcGVybHkgdG8gaW5pdGlhbGl6ZSBpc3ByaW50KCkgdHlwZSBmdW5jdGlvbnMgCiAgICAgKi8KI2lmZGVmIEhBVkVfU0VUTE9DQUxFCiAgICBzZXRsb2NhbGUoTENfQ1RZUEUsICIiKTsKI2VuZGlmCgogICAgc25tcF9kZWJ1Z19pbml0KCk7ICAgIC8qIHNob3VsZCBiZSBkb25lIGZpcnN0LCB0byB0dXJuIG9uIGRlYnVnZ2luZyBBU0FQICovCiAgICBuZXRzbm1wX2NvbnRhaW5lcl9pbml0X2xpc3QoKTsKICAgIGluaXRfY2FsbGJhY2tzKCk7CiAgICBpbml0X3NubXBfbG9nZ2luZygpOwogICAgc25tcF9pbml0X3N0YXRpc3RpY3MoKTsKICAgIHJlZ2lzdGVyX21pYl9oYW5kbGVycygpOwogICAgcmVnaXN0ZXJfZGVmYXVsdF9oYW5kbGVycygpOwogICAgaW5pdF9zbm1wdjModHlwZSk7CiAgICBpbml0X3NubXBfYWxhcm0oKTsKICAgIGluaXRfc25tcF9lbnVtKHR5cGUpOwogICAgaW5pdF92YWNtKCk7CgogICAgcmVhZF9wcmVtaWJfY29uZmlncygpOwojaWZuZGVmIE5FVFNOTVBfRElTQUJMRV9NSUJfTE9BRElORwogICAgbmV0c25tcF9pbml0X21pYigpOwojZW5kaWYgLyogTkVUU05NUF9ESVNBQkxFX01JQl9MT0FESU5HICovCgogICAgcmVhZF9jb25maWdzKCk7Cgp9ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIGVuZCBpbml0X3NubXAoKSAqLwoKdm9pZApzbm1wX3N0b3JlKGNvbnN0IGNoYXIgKnR5cGUpCnsKICAgIERFQlVHTVNHVEwoKCJzbm1wX3N0b3JlIiwgInN0b3Jpbmcgc3R1ZmYuLi5cbiIpKTsKICAgIHNubXBfc2F2ZV9wZXJzaXN0ZW50KHR5cGUpOwogICAgc25tcF9jYWxsX2NhbGxiYWNrcyhTTk1QX0NBTExCQUNLX0xJQlJBUlksIFNOTVBfQ0FMTEJBQ0tfU1RPUkVfREFUQSwgTlVMTCk7CiAgICBzbm1wX2NsZWFuX3BlcnNpc3RlbnQodHlwZSk7Cn0KCgovKioKICogU2h1dHMgZG93biB0aGUgYXBwbGljYXRpb24sIHNhdmluZyBhbnkgbmVlZGVkIHBlcnNpc3RlbnQgc3RvcmFnZSwKICogYW5kIGFwcHJvcHJpYXRlIGNsZWFuIHVwLgogKiAKICogQHBhcmFtIHR5cGUgTGFiZWwgZm9yIHRoZSBjb25maWcgZmlsZSAidHlwZSIgdXNlZAogKgogKiBAcmV0dXJuIHZvaWQKICovCnZvaWQKc25tcF9zaHV0ZG93bihjb25zdCBjaGFyICp0eXBlKQp7CiAgICBzbm1wX3N0b3JlKHR5cGUpOwogICAgc25tcF9jYWxsX2NhbGxiYWNrcyhTTk1QX0NBTExCQUNLX0xJQlJBUlksIFNOTVBfQ0FMTEJBQ0tfU0hVVERPV04sIE5VTEwpOwogICAgc2h1dGRvd25fc25tcF9sb2dnaW5nKCk7CiAgICBzbm1wX2FsYXJtX3VucmVnaXN0ZXJfYWxsKCk7CiAgICBzbm1wX2Nsb3NlX3Nlc3Npb25zKCk7CiNpZm5kZWYgTkVUU05NUF9ESVNBQkxFX01JQl9MT0FESU5HCiAgICBzaHV0ZG93bl9taWIoKTsKI2VuZGlmIC8qIE5FVFNOTVBfRElTQUJMRV9NSUJfTE9BRElORyAqLwogICAgdW5yZWdpc3Rlcl9hbGxfY29uZmlnX2hhbmRsZXJzKCk7CiAgICBuZXRzbm1wX2NvbnRhaW5lcl9mcmVlX2xpc3QoKTsKICAgIGNsZWFyX3NlY19tb2QoKTsKICAgIGNsZWFyX3NubXBfZW51bSgpOwogICAgbmV0c25tcF9jbGVhcl90ZG9tYWluX2xpc3QoKTsKICAgIGNsZWFyX2NhbGxiYWNrKCk7CiAgICBuZXRzbm1wX2RzX3NodXRkb3duKCk7CiAgICBjbGVhcl91c2VyX2xpc3QoKTsKICAgIG5ldHNubXBfY2xlYXJfZGVmYXVsdF90YXJnZXQoKTsKICAgIG5ldHNubXBfY2xlYXJfZGVmYXVsdF9kb21haW4oKTsKICAgIGZyZWVfZXRpbWVsaXN0KCk7CgogICAgaW5pdF9zbm1wX2luaXRfZG9uZSAgPSAwOwogICAgX2luaXRfc25tcF9pbml0X2RvbmUgPSAwOwp9CgoKLyoKICogU2V0cyB1cCB0aGUgc2Vzc2lvbiB3aXRoIHRoZSBzbm1wX3Nlc3Npb24gaW5mb3JtYXRpb24gcHJvdmlkZWQgYnkgdGhlIHVzZXIuCiAqIFRoZW4gb3BlbnMgYW5kIGJpbmRzIHRoZSBuZWNlc3NhcnkgbG93LWxldmVsIHRyYW5zcG9ydC4gIEEgaGFuZGxlIHRvIHRoZQogKiBjcmVhdGVkIHNlc3Npb24gaXMgcmV0dXJuZWQgKHRoaXMgaXMgTk9UIHRoZSBzYW1lIGFzIHRoZSBwb2ludGVyIHBhc3NlZCB0bwogKiBzbm1wX29wZW4oKSkuICBPbiBhbnkgZXJyb3IsIE5VTEwgaXMgcmV0dXJuZWQgYW5kIHNubXBfZXJybm8gaXMgc2V0IHRvIHRoZQogKiBhcHByb3ByaWF0ZSBlcnJvciBjb2RlLgogKi8KbmV0c25tcF9zZXNzaW9uICoKc25tcF9vcGVuKG5ldHNubXBfc2Vzc2lvbiAqc2Vzc2lvbikKewogICAgc3RydWN0IHNlc3Npb25fbGlzdCAqc2xwOwogICAgc2xwID0gKHN0cnVjdCBzZXNzaW9uX2xpc3QgKikgc25tcF9zZXNzX29wZW4oc2Vzc2lvbik7CiAgICBpZiAoIXNscCkgewogICAgICAgIHJldHVybiBOVUxMOwogICAgfQoKICAgIHNubXBfcmVzX2xvY2soTVRfTElCUkFSWV9JRCwgTVRfTElCX1NFU1NJT04pOwogICAgc2xwLT5uZXh0ID0gU2Vzc2lvbnM7CiAgICBTZXNzaW9ucyA9IHNscDsKICAgIHNubXBfcmVzX3VubG9jayhNVF9MSUJSQVJZX0lELCBNVF9MSUJfU0VTU0lPTik7CgogICAgcmV0dXJuIChzbHAtPnNlc3Npb24pOwp9CgovKgogKiBleHRlbmRlZCBvcGVuIAogKi8KbmV0c25tcF9zZXNzaW9uICoKc25tcF9vcGVuX2V4KG5ldHNubXBfc2Vzc2lvbiAqc2Vzc2lvbiwKICAgICAgICAgICAgIGludCAoKmZwcmVfcGFyc2UpCShuZXRzbm1wX3Nlc3Npb24gKiwgbmV0c25tcF90cmFuc3BvcnQgKiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2b2lkICosIGludCksCiAgICAgICAgICAgICBpbnQgKCpmcGFyc2UpCShuZXRzbm1wX3Nlc3Npb24gKiwgbmV0c25tcF9wZHUgKiwgdV9jaGFyICosCgkJCQkgc2l6ZV90KSwKCSAgICAgaW50ICgqZnBvc3RfcGFyc2UpCShuZXRzbm1wX3Nlc3Npb24gKiwgbmV0c25tcF9wZHUgKiwgaW50KSwKCiAgICAgICAgICAgICBpbnQgKCpmYnVpbGQpCShuZXRzbm1wX3Nlc3Npb24gKiwgbmV0c25tcF9wZHUgKiwgdV9jaGFyICosCgkJCQkgc2l6ZV90ICopLAoJICAgICBpbnQgKCpmcmJ1aWxkKQkobmV0c25tcF9zZXNzaW9uICosIG5ldHNubXBfcGR1ICosCgkJCQkgdV9jaGFyICoqLCBzaXplX3QgKiwgc2l6ZV90ICopLAogICAgICAgICAgICAgaW50ICgqZmNoZWNrKQkodV9jaGFyICosIHNpemVfdCkKCSAgICAgKQp7CiAgICBzdHJ1Y3Qgc2Vzc2lvbl9saXN0ICpzbHA7CiAgICBzbHAgPSAoc3RydWN0IHNlc3Npb25fbGlzdCAqKSBzbm1wX3Nlc3Nfb3BlbihzZXNzaW9uKTsKICAgIGlmICghc2xwKSB7CiAgICAgICAgcmV0dXJuIE5VTEw7CiAgICB9CiAgICBzbHAtPmludGVybmFsLT5ob29rX3ByZSA9IGZwcmVfcGFyc2U7CiAgICBzbHAtPmludGVybmFsLT5ob29rX3BhcnNlID0gZnBhcnNlOwogICAgc2xwLT5pbnRlcm5hbC0+aG9va19wb3N0ID0gZnBvc3RfcGFyc2U7CiAgICBzbHAtPmludGVybmFsLT5ob29rX2J1aWxkID0gZmJ1aWxkOwogICAgc2xwLT5pbnRlcm5hbC0+aG9va19yZWFsbG9jX2J1aWxkID0gZnJidWlsZDsKICAgIHNscC0+aW50ZXJuYWwtPmNoZWNrX3BhY2tldCA9IGZjaGVjazsKCiAgICBzbm1wX3Jlc19sb2NrKE1UX0xJQlJBUllfSUQsIE1UX0xJQl9TRVNTSU9OKTsKICAgIHNscC0+bmV4dCA9IFNlc3Npb25zOwogICAgU2Vzc2lvbnMgPSBzbHA7CiAgICBzbm1wX3Jlc191bmxvY2soTVRfTElCUkFSWV9JRCwgTVRfTElCX1NFU1NJT04pOwoKICAgIHJldHVybiAoc2xwLT5zZXNzaW9uKTsKfQoKc3RhdGljIHN0cnVjdCBzZXNzaW9uX2xpc3QgKgpfc2Vzc19jb3B5KG5ldHNubXBfc2Vzc2lvbiAqIGluX3Nlc3Npb24pCnsKICAgIHN0cnVjdCBzZXNzaW9uX2xpc3QgKnNscDsKICAgIHN0cnVjdCBzbm1wX2ludGVybmFsX3Nlc3Npb24gKmlzcDsKICAgIG5ldHNubXBfc2Vzc2lvbiAqc2Vzc2lvbjsKICAgIHN0cnVjdCBzbm1wX3NlY21vZF9kZWYgKnNwdHI7CiAgICBjaGFyICAgICAgICAgICAqY3A7CiAgICB1X2NoYXIgICAgICAgICAqdWNwOwogICAgc2l6ZV90ICAgICAgICAgIGk7CgogICAgaW5fc2Vzc2lvbi0+c19zbm1wX2Vycm5vID0gMDsKICAgIGluX3Nlc3Npb24tPnNfZXJybm8gPSAwOwoKICAgIC8qCiAgICAgKiBDb3B5IHNlc3Npb24gc3RydWN0dXJlIGFuZCBsaW5rIGludG8gbGlzdCAKICAgICAqLwogICAgc2xwID0gKHN0cnVjdCBzZXNzaW9uX2xpc3QgKikgY2FsbG9jKDEsIHNpemVvZihzdHJ1Y3Qgc2Vzc2lvbl9saXN0KSk7CiAgICBpZiAoc2xwID09IE5VTEwpIHsKICAgICAgICBpbl9zZXNzaW9uLT5zX3NubXBfZXJybm8gPSBTTk1QRVJSX01BTExPQzsKICAgICAgICByZXR1cm4gKE5VTEwpOwogICAgfQoKICAgIHNscC0+dHJhbnNwb3J0ID0gTlVMTDsKCiAgICBpc3AgPSAoc3RydWN0IHNubXBfaW50ZXJuYWxfc2Vzc2lvbiAqKWNhbGxvYygxLCBzaXplb2Yoc3RydWN0IHNubXBfaW50ZXJuYWxfc2Vzc2lvbikpOwoKICAgIGlmIChpc3AgPT0gTlVMTCkgewogICAgICAgIHNubXBfc2Vzc19jbG9zZShzbHApOwogICAgICAgIGluX3Nlc3Npb24tPnNfc25tcF9lcnJubyA9IFNOTVBFUlJfTUFMTE9DOwogICAgICAgIHJldHVybiAoTlVMTCk7CiAgICB9CgogICAgc2xwLT5pbnRlcm5hbCA9IGlzcDsKICAgIHNscC0+c2Vzc2lvbiA9IChuZXRzbm1wX3Nlc3Npb24gKiltYWxsb2Moc2l6ZW9mKG5ldHNubXBfc2Vzc2lvbikpOwogICAgaWYgKHNscC0+c2Vzc2lvbiA9PSBOVUxMKSB7CiAgICAgICAgc25tcF9zZXNzX2Nsb3NlKHNscCk7CiAgICAgICAgaW5fc2Vzc2lvbi0+c19zbm1wX2Vycm5vID0gU05NUEVSUl9NQUxMT0M7CiAgICAgICAgcmV0dXJuIChOVUxMKTsKICAgIH0KICAgIG1lbW1vdmUoc2xwLT5zZXNzaW9uLCBpbl9zZXNzaW9uLCBzaXplb2YobmV0c25tcF9zZXNzaW9uKSk7CiAgICBzZXNzaW9uID0gc2xwLT5zZXNzaW9uOwoKICAgIC8qCiAgICAgKiB6ZXJvIG91dCBwb2ludGVycyBzbyBpZiB3ZSBoYXZlIHRvIGZyZWUgdGhlIHNlc3Npb24gd2Ugd29udCBmcmVlIG1lbQogICAgICogb3duZWQgYnkgaW5fc2Vzc2lvbiAKICAgICAqLwogICAgc2Vzc2lvbi0+bG9jYWxuYW1lID0gTlVMTDsKICAgIHNlc3Npb24tPnBlZXJuYW1lID0gTlVMTDsKICAgIHNlc3Npb24tPmNvbW11bml0eSA9IE5VTEw7CiAgICBzZXNzaW9uLT5jb250ZXh0RW5naW5lSUQgPSBOVUxMOwogICAgc2Vzc2lvbi0+Y29udGV4dE5hbWUgPSBOVUxMOwogICAgc2Vzc2lvbi0+c2VjdXJpdHlFbmdpbmVJRCA9IE5VTEw7CiAgICBzZXNzaW9uLT5zZWN1cml0eU5hbWUgPSBOVUxMOwogICAgc2Vzc2lvbi0+c2VjdXJpdHlBdXRoUHJvdG8gPSBOVUxMOwogICAgc2Vzc2lvbi0+c2VjdXJpdHlQcml2UHJvdG8gPSBOVUxMOwogICAgLyoKICAgICAqIHNlc3Npb24gbm93IHBvaW50cyB0byB0aGUgbmV3IHN0cnVjdHVyZSB0aGF0IHN0aWxsIGNvbnRhaW5zIHBvaW50ZXJzIHRvCiAgICAgKiBkYXRhIGFsbG9jYXRlZCBlbHNld2hlcmUuICBTb21lIG9mIHRoaXMgZGF0YSBpcyBjb3BpZWQgdG8gc3BhY2UgbWFsbG9jJ2QKICAgICAqIGhlcmUsIGFuZCB0aGUgcG9pbnRlciByZXBsYWNlZCB3aXRoIHRoZSBuZXcgb25lLgogICAgICovCgogICAgaWYgKGluX3Nlc3Npb24tPnBlZXJuYW1lICE9IE5VTEwpIHsKICAgICAgICBzZXNzaW9uLT5wZWVybmFtZSA9IChjaGFyICopbWFsbG9jKHN0cmxlbihpbl9zZXNzaW9uLT5wZWVybmFtZSkgKyAxKTsKICAgICAgICBpZiAoc2Vzc2lvbi0+cGVlcm5hbWUgPT0gTlVMTCkgewogICAgICAgICAgICBzbm1wX3Nlc3NfY2xvc2Uoc2xwKTsKICAgICAgICAgICAgaW5fc2Vzc2lvbi0+c19zbm1wX2Vycm5vID0gU05NUEVSUl9NQUxMT0M7CiAgICAgICAgICAgIHJldHVybiAoTlVMTCk7CiAgICAgICAgfQogICAgICAgIHN0cmNweShzZXNzaW9uLT5wZWVybmFtZSwgaW5fc2Vzc2lvbi0+cGVlcm5hbWUpOwogICAgfQoKICAgIC8qCiAgICAgKiBGaWxsIGluIGRlZmF1bHRzIGlmIG5lY2Vzc2FyeSAKICAgICAqLwojaWYgIWRlZmluZWQoTkVUU05NUF9ESVNBQkxFX1NOTVBWMSkgfHwgIWRlZmluZWQoTkVUU05NUF9ESVNBQkxFX1NOTVBWMkMpCiAgICBpZiAoaW5fc2Vzc2lvbi0+Y29tbXVuaXR5X2xlbiAhPSBTTk1QX0RFRkFVTFRfQ09NTVVOSVRZX0xFTikgewogICAgICAgIHVjcCA9ICh1X2NoYXIgKikgbWFsbG9jKGluX3Nlc3Npb24tPmNvbW11bml0eV9sZW4pOwogICAgICAgIGlmICh1Y3AgIT0gTlVMTCkKICAgICAgICAgICAgbWVtbW92ZSh1Y3AsIGluX3Nlc3Npb24tPmNvbW11bml0eSwgaW5fc2Vzc2lvbi0+Y29tbXVuaXR5X2xlbik7CiAgICB9IGVsc2UgewogICAgICAgIGlmICgoY3AgPSBuZXRzbm1wX2RzX2dldF9zdHJpbmcoTkVUU05NUF9EU19MSUJSQVJZX0lELCAKCQkJCQlORVRTTk1QX0RTX0xJQl9DT01NVU5JVFkpKSAhPSBOVUxMKSB7CiAgICAgICAgICAgIHNlc3Npb24tPmNvbW11bml0eV9sZW4gPSBzdHJsZW4oY3ApOwogICAgICAgICAgICB1Y3AgPSAodV9jaGFyICopIG1hbGxvYyhzZXNzaW9uLT5jb21tdW5pdHlfbGVuKTsKICAgICAgICAgICAgaWYgKHVjcCkKICAgICAgICAgICAgICAgIG1lbW1vdmUodWNwLCBjcCwgc2Vzc2lvbi0+Y29tbXVuaXR5X2xlbik7CiAgICAgICAgfSBlbHNlIHsKI2lmZGVmIE5FVFNOTVBfTk9fWkVST0xFTkdUSF9DT01NVU5JVFkKICAgICAgICAgICAgc2Vzc2lvbi0+Y29tbXVuaXR5X2xlbiA9IHN0cmxlbihERUZBVUxUX0NPTU1VTklUWSk7CiAgICAgICAgICAgIHVjcCA9ICh1X2NoYXIgKikgbWFsbG9jKHNlc3Npb24tPmNvbW11bml0eV9sZW4pOwogICAgICAgICAgICBpZiAodWNwKQogICAgICAgICAgICAgICAgbWVtbW92ZSh1Y3AsIERFRkFVTFRfQ09NTVVOSVRZLCBzZXNzaW9uLT5jb21tdW5pdHlfbGVuKTsKI2Vsc2UKICAgICAgICAgICAgdWNwID0gKHVfY2hhciAqKSBzdHJkdXAoIiIpOwojZW5kaWYKICAgICAgICB9CiAgICB9CgogICAgaWYgKHVjcCA9PSBOVUxMKSB7CiAgICAgICAgc25tcF9zZXNzX2Nsb3NlKHNscCk7CiAgICAgICAgaW5fc2Vzc2lvbi0+c19zbm1wX2Vycm5vID0gU05NUEVSUl9NQUxMT0M7CiAgICAgICAgcmV0dXJuIChOVUxMKTsKICAgIH0KICAgIHNlc3Npb24tPmNvbW11bml0eSA9IHVjcDsgICAvKiByZXBsYWNlIHBvaW50ZXIgd2l0aCBwb2ludGVyIHRvIG5ldyBkYXRhICovCiNlbmRpZgoKICAgIGlmIChzZXNzaW9uLT5zZWN1cml0eUxldmVsIDw9IDApIHsKICAgICAgICBzZXNzaW9uLT5zZWN1cml0eUxldmVsID0KICAgICAgICAgICAgbmV0c25tcF9kc19nZXRfaW50KE5FVFNOTVBfRFNfTElCUkFSWV9JRCwgTkVUU05NUF9EU19MSUJfU0VDTEVWRUwpOwogICAgfQoKICAgIGlmIChzZXNzaW9uLT5zZWN1cml0eUxldmVsID09IDApCiAgICAgICAgc2Vzc2lvbi0+c2VjdXJpdHlMZXZlbCA9IFNOTVBfU0VDX0xFVkVMX05PQVVUSDsKCiAgICBpZiAoaW5fc2Vzc2lvbi0+c2VjdXJpdHlBdXRoUHJvdG9MZW4gPiAwKSB7CiAgICAgICAgc2Vzc2lvbi0+c2VjdXJpdHlBdXRoUHJvdG8gPQogICAgICAgICAgICBzbm1wX2R1cGxpY2F0ZV9vYmppZChpbl9zZXNzaW9uLT5zZWN1cml0eUF1dGhQcm90bywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW5fc2Vzc2lvbi0+c2VjdXJpdHlBdXRoUHJvdG9MZW4pOwogICAgICAgIGlmIChzZXNzaW9uLT5zZWN1cml0eUF1dGhQcm90byA9PSBOVUxMKSB7CiAgICAgICAgICAgIHNubXBfc2Vzc19jbG9zZShzbHApOwogICAgICAgICAgICBpbl9zZXNzaW9uLT5zX3NubXBfZXJybm8gPSBTTk1QRVJSX01BTExPQzsKICAgICAgICAgICAgcmV0dXJuIChOVUxMKTsKICAgICAgICB9CiAgICB9IGVsc2UgaWYgKGdldF9kZWZhdWx0X2F1dGh0eXBlKCZpKSAhPSBOVUxMKSB7CiAgICAgICAgc2Vzc2lvbi0+c2VjdXJpdHlBdXRoUHJvdG8gPQogICAgICAgICAgICBzbm1wX2R1cGxpY2F0ZV9vYmppZChnZXRfZGVmYXVsdF9hdXRodHlwZShOVUxMKSwgaSk7CiAgICAgICAgc2Vzc2lvbi0+c2VjdXJpdHlBdXRoUHJvdG9MZW4gPSBpOwogICAgfQoKICAgIGlmIChpbl9zZXNzaW9uLT5zZWN1cml0eVByaXZQcm90b0xlbiA+IDApIHsKICAgICAgICBzZXNzaW9uLT5zZWN1cml0eVByaXZQcm90byA9CiAgICAgICAgICAgIHNubXBfZHVwbGljYXRlX29iamlkKGluX3Nlc3Npb24tPnNlY3VyaXR5UHJpdlByb3RvLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbl9zZXNzaW9uLT5zZWN1cml0eVByaXZQcm90b0xlbik7CiAgICAgICAgaWYgKHNlc3Npb24tPnNlY3VyaXR5UHJpdlByb3RvID09IE5VTEwpIHsKICAgICAgICAgICAgc25tcF9zZXNzX2Nsb3NlKHNscCk7CiAgICAgICAgICAgIGluX3Nlc3Npb24tPnNfc25tcF9lcnJubyA9IFNOTVBFUlJfTUFMTE9DOwogICAgICAgICAgICByZXR1cm4gKE5VTEwpOwogICAgICAgIH0KICAgIH0gZWxzZSBpZiAoZ2V0X2RlZmF1bHRfcHJpdnR5cGUoJmkpICE9IE5VTEwpIHsKICAgICAgICBzZXNzaW9uLT5zZWN1cml0eVByaXZQcm90byA9CiAgICAgICAgICAgIHNubXBfZHVwbGljYXRlX29iamlkKGdldF9kZWZhdWx0X3ByaXZ0eXBlKE5VTEwpLCBpKTsKICAgICAgICBzZXNzaW9uLT5zZWN1cml0eVByaXZQcm90b0xlbiA9IGk7CiAgICB9CgogICAgaWYgKGluX3Nlc3Npb24tPnNlY3VyaXR5RW5naW5lSURMZW4gPiAwKSB7CiAgICAgICAgdWNwID0gKHVfY2hhciAqKSBtYWxsb2MoaW5fc2Vzc2lvbi0+c2VjdXJpdHlFbmdpbmVJRExlbik7CiAgICAgICAgaWYgKHVjcCA9PSBOVUxMKSB7CiAgICAgICAgICAgIHNubXBfc2Vzc19jbG9zZShzbHApOwogICAgICAgICAgICBpbl9zZXNzaW9uLT5zX3NubXBfZXJybm8gPSBTTk1QRVJSX01BTExPQzsKICAgICAgICAgICAgcmV0dXJuIChOVUxMKTsKICAgICAgICB9CiAgICAgICAgbWVtbW92ZSh1Y3AsIGluX3Nlc3Npb24tPnNlY3VyaXR5RW5naW5lSUQsCiAgICAgICAgICAgICAgICBpbl9zZXNzaW9uLT5zZWN1cml0eUVuZ2luZUlETGVuKTsKICAgICAgICBzZXNzaW9uLT5zZWN1cml0eUVuZ2luZUlEID0gdWNwOwoKICAgIH0KCiAgICBpZiAoaW5fc2Vzc2lvbi0+Y29udGV4dEVuZ2luZUlETGVuID4gMCkgewogICAgICAgIHVjcCA9ICh1X2NoYXIgKikgbWFsbG9jKGluX3Nlc3Npb24tPmNvbnRleHRFbmdpbmVJRExlbik7CiAgICAgICAgaWYgKHVjcCA9PSBOVUxMKSB7CiAgICAgICAgICAgIHNubXBfc2Vzc19jbG9zZShzbHApOwogICAgICAgICAgICBpbl9zZXNzaW9uLT5zX3NubXBfZXJybm8gPSBTTk1QRVJSX01BTExPQzsKICAgICAgICAgICAgcmV0dXJuIChOVUxMKTsKICAgICAgICB9CiAgICAgICAgbWVtbW92ZSh1Y3AsIGluX3Nlc3Npb24tPmNvbnRleHRFbmdpbmVJRCwKICAgICAgICAgICAgICAgIGluX3Nlc3Npb24tPmNvbnRleHRFbmdpbmVJRExlbik7CiAgICAgICAgc2Vzc2lvbi0+Y29udGV4dEVuZ2luZUlEID0gdWNwOwogICAgfSBlbHNlIGlmIChpbl9zZXNzaW9uLT5zZWN1cml0eUVuZ2luZUlETGVuID4gMCkgewogICAgICAgIC8qCiAgICAgICAgICogZGVmYXVsdCBjb250ZXh0RW5naW5lSUQgdG8gc2VjdXJpdHlFbmdpbmVJRExlbiBpZiBkZWZpbmVkIAogICAgICAgICAqLwogICAgICAgIHVjcCA9ICh1X2NoYXIgKikgbWFsbG9jKGluX3Nlc3Npb24tPnNlY3VyaXR5RW5naW5lSURMZW4pOwogICAgICAgIGlmICh1Y3AgPT0gTlVMTCkgewogICAgICAgICAgICBzbm1wX3Nlc3NfY2xvc2Uoc2xwKTsKICAgICAgICAgICAgaW5fc2Vzc2lvbi0+c19zbm1wX2Vycm5vID0gU05NUEVSUl9NQUxMT0M7CiAgICAgICAgICAgIHJldHVybiAoTlVMTCk7CiAgICAgICAgfQogICAgICAgIG1lbW1vdmUodWNwLCBpbl9zZXNzaW9uLT5zZWN1cml0eUVuZ2luZUlELAogICAgICAgICAgICAgICAgaW5fc2Vzc2lvbi0+c2VjdXJpdHlFbmdpbmVJRExlbik7CiAgICAgICAgc2Vzc2lvbi0+Y29udGV4dEVuZ2luZUlEID0gdWNwOwogICAgICAgIHNlc3Npb24tPmNvbnRleHRFbmdpbmVJRExlbiA9IGluX3Nlc3Npb24tPnNlY3VyaXR5RW5naW5lSURMZW47CiAgICB9CgogICAgaWYgKGluX3Nlc3Npb24tPmNvbnRleHROYW1lKSB7CiAgICAgICAgc2Vzc2lvbi0+Y29udGV4dE5hbWUgPSBzdHJkdXAoaW5fc2Vzc2lvbi0+Y29udGV4dE5hbWUpOwogICAgICAgIGlmIChzZXNzaW9uLT5jb250ZXh0TmFtZSA9PSBOVUxMKSB7CiAgICAgICAgICAgIHNubXBfc2Vzc19jbG9zZShzbHApOwogICAgICAgICAgICByZXR1cm4gKE5VTEwpOwogICAgICAgIH0KICAgICAgICBzZXNzaW9uLT5jb250ZXh0TmFtZUxlbiA9IGluX3Nlc3Npb24tPmNvbnRleHROYW1lTGVuOwogICAgfSBlbHNlIHsKICAgICAgICBpZiAoKGNwID0gbmV0c25tcF9kc19nZXRfc3RyaW5nKE5FVFNOTVBfRFNfTElCUkFSWV9JRCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5FVFNOTVBfRFNfTElCX0NPTlRFWFQpKSAhPSBOVUxMKQogICAgICAgICAgICBjcCA9IHN0cmR1cChjcCk7CiAgICAgICAgZWxzZQogICAgICAgICAgICBjcCA9IHN0cmR1cChTTk1QX0RFRkFVTFRfQ09OVEVYVCk7CiAgICAgICAgaWYgKGNwID09IE5VTEwpIHsKICAgICAgICAgICAgc25tcF9zZXNzX2Nsb3NlKHNscCk7CiAgICAgICAgICAgIHJldHVybiAoTlVMTCk7CiAgICAgICAgfQogICAgICAgIHNlc3Npb24tPmNvbnRleHROYW1lID0gY3A7CiAgICAgICAgc2Vzc2lvbi0+Y29udGV4dE5hbWVMZW4gPSBzdHJsZW4oY3ApOwogICAgfQoKICAgIGlmIChpbl9zZXNzaW9uLT5zZWN1cml0eU5hbWUpIHsKICAgICAgICBzZXNzaW9uLT5zZWN1cml0eU5hbWUgPSBzdHJkdXAoaW5fc2Vzc2lvbi0+c2VjdXJpdHlOYW1lKTsKICAgICAgICBpZiAoc2Vzc2lvbi0+c2VjdXJpdHlOYW1lID09IE5VTEwpIHsKICAgICAgICAgICAgc25tcF9zZXNzX2Nsb3NlKHNscCk7CiAgICAgICAgICAgIHJldHVybiAoTlVMTCk7CiAgICAgICAgfQogICAgfSBlbHNlIGlmICgoY3AgPSBuZXRzbm1wX2RzX2dldF9zdHJpbmcoTkVUU05NUF9EU19MSUJSQVJZX0lELCAKCQkJCQkgICBORVRTTk1QX0RTX0xJQl9TRUNOQU1FKSkgIT0gTlVMTCkgewogICAgICAgIGNwID0gc3RyZHVwKGNwKTsKICAgICAgICBpZiAoY3AgPT0gTlVMTCkgewogICAgICAgICAgICBzbm1wX3Nlc3NfY2xvc2Uoc2xwKTsKICAgICAgICAgICAgcmV0dXJuIChOVUxMKTsKICAgICAgICB9CiAgICAgICAgc2Vzc2lvbi0+c2VjdXJpdHlOYW1lID0gY3A7CiAgICAgICAgc2Vzc2lvbi0+c2VjdXJpdHlOYW1lTGVuID0gc3RybGVuKGNwKTsKICAgIH0KCiAgICBpZiAoKGluX3Nlc3Npb24tPnNlY3VyaXR5QXV0aEtleUxlbiA8PSAwKSAmJgogICAgICAgICgoY3AgPSBuZXRzbm1wX2RzX2dldF9zdHJpbmcoTkVUU05NUF9EU19MSUJSQVJZX0lELCAKCQkJCSAgICAgTkVUU05NUF9EU19MSUJfQVVUSE1BU1RFUktFWSkpKSkgewogICAgICAgIHNpemVfdCBidWZsZW4gPSBzaXplb2Yoc2Vzc2lvbi0+c2VjdXJpdHlBdXRoS2V5KTsKICAgICAgICB1X2NoYXIgKnRtcHAgPSBzZXNzaW9uLT5zZWN1cml0eUF1dGhLZXk7CiAgICAgICAgc2Vzc2lvbi0+c2VjdXJpdHlBdXRoS2V5TGVuID0gMDsKICAgICAgICAvKiBpdCB3aWxsIGJlIGEgaGV4IHN0cmluZyAqLwogICAgICAgIGlmICghc25tcF9oZXhfdG9fYmluYXJ5KCZ0bXBwLCAmYnVmbGVuLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZzZXNzaW9uLT5zZWN1cml0eUF1dGhLZXlMZW4sIDAsIGNwKSkgewogICAgICAgICAgICBzbm1wX3NldF9kZXRhaWwoImVycm9yIHBhcnNpbmcgYXV0aGVudGljYXRpb24gbWFzdGVyIGtleSIpOwogICAgICAgICAgICBzbm1wX3Nlc3NfY2xvc2Uoc2xwKTsKICAgICAgICAgICAgcmV0dXJuIE5VTEw7CiAgICAgICAgfQogICAgfSBlbHNlIGlmICgoaW5fc2Vzc2lvbi0+c2VjdXJpdHlBdXRoS2V5TGVuIDw9IDApICYmCiAgICAgICAgKChjcCA9IG5ldHNubXBfZHNfZ2V0X3N0cmluZyhORVRTTk1QX0RTX0xJQlJBUllfSUQsIAoJCQkJICAgICBORVRTTk1QX0RTX0xJQl9BVVRIUEFTU1BIUkFTRSkpIHx8CiAgICAgICAgIChjcCA9IG5ldHNubXBfZHNfZ2V0X3N0cmluZyhORVRTTk1QX0RTX0xJQlJBUllfSUQsIAoJCQkJICAgICBORVRTTk1QX0RTX0xJQl9QQVNTUEhSQVNFKSkpKSB7CiAgICAgICAgc2Vzc2lvbi0+c2VjdXJpdHlBdXRoS2V5TGVuID0gVVNNX0FVVEhfS1VfTEVOOwogICAgICAgIGlmIChnZW5lcmF0ZV9LdShzZXNzaW9uLT5zZWN1cml0eUF1dGhQcm90bywKICAgICAgICAgICAgICAgICAgICAgICAgc2Vzc2lvbi0+c2VjdXJpdHlBdXRoUHJvdG9MZW4sCiAgICAgICAgICAgICAgICAgICAgICAgICh1X2NoYXIgKikgY3AsIHN0cmxlbihjcCksCiAgICAgICAgICAgICAgICAgICAgICAgIHNlc3Npb24tPnNlY3VyaXR5QXV0aEtleSwKICAgICAgICAgICAgICAgICAgICAgICAgJnNlc3Npb24tPnNlY3VyaXR5QXV0aEtleUxlbikgIT0gU05NUEVSUl9TVUNDRVNTKSB7CiAgICAgICAgICAgIHNubXBfc2V0X2RldGFpbAogICAgICAgICAgICAgICAgKCJFcnJvciBnZW5lcmF0aW5nIGEga2V5IChLdSkgZnJvbSB0aGUgc3VwcGxpZWQgYXV0aGVudGljYXRpb24gcGFzcyBwaHJhc2UuIik7CiAgICAgICAgICAgIHNubXBfc2Vzc19jbG9zZShzbHApOwogICAgICAgICAgICByZXR1cm4gTlVMTDsKICAgICAgICB9CiAgICB9CgogICAgCiAgICBpZiAoKGluX3Nlc3Npb24tPnNlY3VyaXR5UHJpdktleUxlbiA8PSAwKSAmJgogICAgICAgICgoY3AgPSBuZXRzbm1wX2RzX2dldF9zdHJpbmcoTkVUU05NUF9EU19MSUJSQVJZX0lELCAKCQkJCSAgICAgTkVUU05NUF9EU19MSUJfUFJJVk1BU1RFUktFWSkpKSkgewogICAgICAgIHNpemVfdCBidWZsZW4gPSBzaXplb2Yoc2Vzc2lvbi0+c2VjdXJpdHlQcml2S2V5KTsKICAgICAgICB1X2NoYXIgKnRtcHAgPSBzZXNzaW9uLT5zZWN1cml0eVByaXZLZXk7CiAgICAgICAgc2Vzc2lvbi0+c2VjdXJpdHlQcml2S2V5TGVuID0gMDsKICAgICAgICAvKiBpdCB3aWxsIGJlIGEgaGV4IHN0cmluZyAqLwogICAgICAgIGlmICghc25tcF9oZXhfdG9fYmluYXJ5KCZ0bXBwLCAmYnVmbGVuLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZzZXNzaW9uLT5zZWN1cml0eVByaXZLZXlMZW4sIDAsIGNwKSkgewogICAgICAgICAgICBzbm1wX3NldF9kZXRhaWwoImVycm9yIHBhcnNpbmcgZW5jcnlwdGlvbiBtYXN0ZXIga2V5Iik7CiAgICAgICAgICAgIHNubXBfc2Vzc19jbG9zZShzbHApOwogICAgICAgICAgICByZXR1cm4gTlVMTDsKICAgICAgICB9CiAgICB9IGVsc2UgaWYgKChpbl9zZXNzaW9uLT5zZWN1cml0eVByaXZLZXlMZW4gPD0gMCkgJiYKICAgICAgICAoKGNwID0gbmV0c25tcF9kc19nZXRfc3RyaW5nKE5FVFNOTVBfRFNfTElCUkFSWV9JRCwgCgkJCQkgICAgIE5FVFNOTVBfRFNfTElCX1BSSVZQQVNTUEhSQVNFKSkgfHwKICAgICAgICAgKGNwID0gbmV0c25tcF9kc19nZXRfc3RyaW5nKE5FVFNOTVBfRFNfTElCUkFSWV9JRCwgCgkJCQkgICAgIE5FVFNOTVBfRFNfTElCX1BBU1NQSFJBU0UpKSkpIHsKICAgICAgICBzZXNzaW9uLT5zZWN1cml0eVByaXZLZXlMZW4gPSBVU01fUFJJVl9LVV9MRU47CiAgICAgICAgaWYgKGdlbmVyYXRlX0t1KHNlc3Npb24tPnNlY3VyaXR5QXV0aFByb3RvLAogICAgICAgICAgICAgICAgICAgICAgICBzZXNzaW9uLT5zZWN1cml0eUF1dGhQcm90b0xlbiwKICAgICAgICAgICAgICAgICAgICAgICAgKHVfY2hhciAqKSBjcCwgc3RybGVuKGNwKSwKICAgICAgICAgICAgICAgICAgICAgICAgc2Vzc2lvbi0+c2VjdXJpdHlQcml2S2V5LAogICAgICAgICAgICAgICAgICAgICAgICAmc2Vzc2lvbi0+c2VjdXJpdHlQcml2S2V5TGVuKSAhPSBTTk1QRVJSX1NVQ0NFU1MpIHsKICAgICAgICAgICAgc25tcF9zZXRfZGV0YWlsCiAgICAgICAgICAgICAgICAoIkVycm9yIGdlbmVyYXRpbmcgYSBrZXkgKEt1KSBmcm9tIHRoZSBzdXBwbGllZCBwcml2YWN5IHBhc3MgcGhyYXNlLiIpOwogICAgICAgICAgICBzbm1wX3Nlc3NfY2xvc2Uoc2xwKTsKICAgICAgICAgICAgcmV0dXJuIE5VTEw7CiAgICAgICAgfQogICAgfQoKICAgIGlmIChzZXNzaW9uLT5yZXRyaWVzID09IFNOTVBfREVGQVVMVF9SRVRSSUVTKQogICAgICAgIHNlc3Npb24tPnJldHJpZXMgPSBERUZBVUxUX1JFVFJJRVM7CiAgICBpZiAoc2Vzc2lvbi0+dGltZW91dCA9PSBTTk1QX0RFRkFVTFRfVElNRU9VVCkKICAgICAgICBzZXNzaW9uLT50aW1lb3V0ID0gREVGQVVMVF9USU1FT1VUOwogICAgc2Vzc2lvbi0+c2Vzc2lkID0gc25tcF9nZXRfbmV4dF9zZXNzaWQoKTsKCiAgICBzbm1wX2NhbGxfY2FsbGJhY2tzKFNOTVBfQ0FMTEJBQ0tfTElCUkFSWSwgU05NUF9DQUxMQkFDS19TRVNTSU9OX0lOSVQsCiAgICAgICAgICAgICAgICAgICAgICAgIHNlc3Npb24pOwoKICAgIGlmICgoc3B0ciA9IGZpbmRfc2VjX21vZChzZXNzaW9uLT5zZWN1cml0eU1vZGVsKSkgIT0gTlVMTCAmJgogICAgICAgIHNwdHItPnNlc3Npb25fb3BlbiAhPSBOVUxMKSB7CiAgICAgICAgLyoKICAgICAgICAgKiBzZWN1cml0eSBtb2R1bGUgc3BlY2lmaWMgaW5pYWxpemF0aW9uIAogICAgICAgICAqLwogICAgICAgICgqc3B0ci0+c2Vzc2lvbl9vcGVuKSAoc2Vzc2lvbik7CiAgICB9CgogICAgcmV0dXJuIChzbHApOwp9CgpzdGF0aWMgc3RydWN0IHNlc3Npb25fbGlzdCAqCnNubXBfc2Vzc19jb3B5KG5ldHNubXBfc2Vzc2lvbiAqIHBzcykKewogICAgc3RydWN0IHNlc3Npb25fbGlzdCAqcHNsOwogICAgcHNsID0gX3Nlc3NfY29weShwc3MpOwogICAgaWYgKCFwc2wpIHsKICAgICAgICBpZiAoIXBzcy0+c19zbm1wX2Vycm5vKSB7CiAgICAgICAgICAgIHBzcy0+c19zbm1wX2Vycm5vID0gU05NUEVSUl9HRU5FUlI7CiAgICAgICAgfQogICAgICAgIFNFVF9TTk1QX0VSUk9SKHBzcy0+c19zbm1wX2Vycm5vKTsKICAgIH0KICAgIHJldHVybiBwc2w7Cn0KCi8qKgogKiBwcm9iZSBmb3IgcGVlciBlbmdpbmVJRAogKgogKiBAcGFyYW0gc2xwICAgICAgICAgc2Vzc2lvbiBsaXN0IHBvaW50ZXIuCiAqIEBwYXJhbSBpbl9zZXNzaW9uICBzZXNzaW9uIGZvciBlcnJvcnMKICoKICogQG5vdGUKICogIC0gY2FsbGVkIGJ5IF9zZXNzX29wZW4oKSwgc25tcF9zZXNzX2FkZF9leCgpCiAqICAtIGluX3Nlc3Npb24gaXMgdGhlIHVzZXIgc3VwcGxpZWQgc2Vzc2lvbiBwcm92aWRlZCB0byB0aG9zZSBmdW5jdGlvbnMuCiAqICAtIHRoZSBmaXJzdCBzZXNzaW9uIGluIHNscCBzaG91bGQgdGhlIGludGVybmFsIGFsbG9jYXRlZCBjb3B5IG9mIGluX3Nlc3Npb24KICoKICogQHJldHVybiAwIDogZXJyb3IKICogQHJldHVybiAxIDogb2sKICoKICovCmludApzbm1wdjNfZW5naW5lSURfcHJvYmUoc3RydWN0IHNlc3Npb25fbGlzdCAqc2xwLAogICAgICAgICAgICAgICAgICAgICAgbmV0c25tcF9zZXNzaW9uICogaW5fc2Vzc2lvbikKewogICAgbmV0c25tcF9wZHUgICAgKnBkdSA9IE5VTEwsICpyZXNwb25zZSA9IE5VTEw7CiAgICBuZXRzbm1wX3Nlc3Npb24gKnNlc3Npb247CiAgICB1bnNpZ25lZCBpbnQgICAgaTsKICAgIGludCAgICAgICAgICAgICBzdGF0dXM7CgogICAgaWYgKHNscCA9PSBOVUxMIHx8IHNscC0+c2Vzc2lvbiA9PSBOVUxMKSB7CiAgICAgICAgcmV0dXJuIDA7CiAgICB9CgogICAgc2Vzc2lvbiA9IHNscC0+c2Vzc2lvbjsKCiAgICAvKgogICAgICogSWYgd2UgYXJlIG9wZW5pbmcgYSBWMyBzZXNzaW9uIGFuZCB3ZSBkb24ndCBrbm93IGVuZ2luZUlEIHdlIG11c3QgcHJvYmUKICAgICAqIGl0IC0tIHRoaXMgbXVzdCBiZSBkb25lIGFmdGVyIHRoZSBzZXNzaW9uIGlzIGNyZWF0ZWQgYW5kIGluc2VydGVkIGluIHRoZQogICAgICogbGlzdCBzbyB0aGF0IHRoZSByZXNwb25zZSBjYW4gaGFuZGxlZCBjb3JyZWN0bHkuIAogICAgICovCgogICAgaWYgKChzZXNzaW9uLT5mbGFncyAmIFNOTVBfRkxBR1NfRE9OVF9QUk9CRSkgPT0gU05NUF9GTEFHU19ET05UX1BST0JFKQogICAgICAgIHJldHVybiAxOwoKICAgIGlmIChzZXNzaW9uLT52ZXJzaW9uID09IFNOTVBfVkVSU0lPTl8zKSB7CiAgICAgICAgaWYgKHNlc3Npb24tPnNlY3VyaXR5RW5naW5lSURMZW4gPT0gMCkgewogICAgICAgICAgICBpZiAoc25tcHYzX2J1aWxkX3Byb2JlX3BkdSgmcGR1KSAhPSAwKSB7CiAgICAgICAgICAgICAgICBERUJVR01TR1RMKCgic25tcF9hcGkiLCAidW5hYmxlIHRvIGNyZWF0ZSBwcm9iZSBQRFVcbiIpKTsKICAgICAgICAgICAgICAgIHJldHVybiAwOwogICAgICAgICAgICB9CiAgICAgICAgICAgIERFQlVHTVNHVEwoKCJzbm1wX2FwaSIsICJwcm9iaW5nIGZvciBlbmdpbmVJRC4uLlxuIikpOwogICAgICAgICAgICBzZXNzaW9uLT5mbGFncyB8PSBTTk1QX0ZMQUdTX0RPTlRfUFJPQkU7IC8qIHByZXZlbnQgcmVjdXJzaW9uICovCiAgICAgICAgICAgIHN0YXR1cyA9IHNubXBfc2Vzc19zeW5jaF9yZXNwb25zZShzbHAsIHBkdSwgJnJlc3BvbnNlKTsKCiAgICAgICAgICAgIGlmICgocmVzcG9uc2UgPT0gTlVMTCkgJiYgKHN0YXR1cyA9PSBTVEFUX1NVQ0NFU1MpKSB7CiAgICAgICAgICAgICAgICBzdGF0dXMgPSBTVEFUX0VSUk9SOwogICAgICAgICAgICB9CgogICAgICAgICAgICBzd2l0Y2ggKHN0YXR1cykgewogICAgICAgICAgICBjYXNlIFNUQVRfU1VDQ0VTUzoKICAgICAgICAgICAgICAgIGluX3Nlc3Npb24tPnNfc25tcF9lcnJubyA9IFNOTVBFUlJfSU5WQUxJRF9NU0c7IC8qIFhYPz8gKi8KICAgICAgICAgICAgICAgIERFQlVHTVNHVEwoKCJzbm1wX3Nlc3Nfb3BlbiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAiZXJyb3I6IGV4cGVjdGVkIFJlcG9ydCBhcyByZXNwb25zZSB0byBwcm9iZTogJXMgKCVkKVxuIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNubXBfZXJyc3RyaW5nKHJlc3BvbnNlLT5lcnJzdGF0KSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlc3BvbnNlLT5lcnJzdGF0KSk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgY2FzZSBTVEFUX0VSUk9SOiAgIC8qIHRoaXMgaXMgd2hhdCB3ZSBleHBlY3RlZCAtPiBSZXBvcnQgPT0gU1RBVF9FUlJPUiAqLwogICAgICAgICAgICAgICAgaW5fc2Vzc2lvbi0+c19zbm1wX2Vycm5vID0gU05NUEVSUl9VTktOT1dOX0VOR19JRDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlIFNUQVRfVElNRU9VVDoKICAgICAgICAgICAgICAgIGluX3Nlc3Npb24tPnNfc25tcF9lcnJubyA9IFNOTVBFUlJfVElNRU9VVDsKICAgICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgICAgIERFQlVHTVNHVEwoKCJzbm1wX3Nlc3Nfb3BlbiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAidW5hYmxlIHRvIGNvbm5lY3Qgd2l0aCByZW1vdGUgZW5naW5lOiAlcyAoJWQpXG4iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgc25tcF9hcGlfZXJyc3RyaW5nKHNlc3Npb24tPnNfc25tcF9lcnJubyksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZXNzaW9uLT5zX3NubXBfZXJybm8pKTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAoc2xwLT5zZXNzaW9uLT5zZWN1cml0eUVuZ2luZUlETGVuID09IDApIHsKICAgICAgICAgICAgICAgIERFQlVHTVNHVEwoKCJzbm1wX2FwaSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAidW5hYmxlIHRvIGRldGVybWluZSByZW1vdGUgZW5naW5lIElEXG4iKSk7CiAgICAgICAgICAgICAgICAvKiBjbGVhciB0aGUgZmxhZyBzbyB0aGF0IHByb2JlIG9jY3VycyBvbiBuZXh0IGluZm9ybSAqLwogICAgICAgICAgICAgICAgc2Vzc2lvbi0+ZmxhZ3MgJj0gflNOTVBfRkxBR1NfRE9OVF9QUk9CRTsKICAgICAgICAgICAgICAgIHJldHVybiAwOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpbl9zZXNzaW9uLT5zX3NubXBfZXJybm8gPSBTTk1QRVJSX1NVQ0NFU1M7CiAgICAgICAgICAgIGlmIChzbm1wX2dldF9kb19kZWJ1Z2dpbmcoKSkgewogICAgICAgICAgICAgICAgREVCVUdNU0dUTCgoInNubXBfc2Vzc19vcGVuIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICIgIHByb2JlIGZvdW5kIGVuZ2luZUlEOiAgIikpOwogICAgICAgICAgICAgICAgZm9yIChpID0gMDsgaSA8IHNscC0+c2Vzc2lvbi0+c2VjdXJpdHlFbmdpbmVJRExlbjsgaSsrKQogICAgICAgICAgICAgICAgICAgIERFQlVHTVNHKCgic25tcF9zZXNzX29wZW4iLCAiJTAyeCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNscC0+c2Vzc2lvbi0+c2VjdXJpdHlFbmdpbmVJRFtpXSkpOwogICAgICAgICAgICAgICAgREVCVUdNU0coKCJzbm1wX3Nlc3Nfb3BlbiIsICJcbiIpKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgLyoKICAgICAgICAgKiBpZiBib290L3RpbWUgc3VwcGxpZWQgc2V0IGl0IGZvciB0aGlzIGVuZ2luZUlEIAogICAgICAgICAqLwogICAgICAgIGlmIChzZXNzaW9uLT5lbmdpbmVCb290cyB8fCBzZXNzaW9uLT5lbmdpbmVUaW1lKSB7CiAgICAgICAgICAgIHNldF9lbmdpbmV0aW1lKHNlc3Npb24tPnNlY3VyaXR5RW5naW5lSUQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlc3Npb24tPnNlY3VyaXR5RW5naW5lSURMZW4sCiAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlc3Npb24tPmVuZ2luZUJvb3RzLCBzZXNzaW9uLT5lbmdpbmVUaW1lLAogICAgICAgICAgICAgICAgICAgICAgICAgICBUUlVFKTsKICAgICAgICB9CgogICAgICAgIGlmIChjcmVhdGVfdXNlcl9mcm9tX3Nlc3Npb24oc2xwLT5zZXNzaW9uKSAhPSBTTk1QRVJSX1NVQ0NFU1MpIHsKICAgICAgICAgICAgaW5fc2Vzc2lvbi0+c19zbm1wX2Vycm5vID0gU05NUEVSUl9VTktOT1dOX1VTRVJfTkFNRTsgICAgICAgLyogWFg/PyAqLwogICAgICAgICAgICBERUJVR01TR1RMKCgic25tcF9hcGkiLAogICAgICAgICAgICAgICAgICAgICAgICAic25tcHYzX2VuZ2luZV9wcm9iZSgpOiBmYWlsZWQoMikgdG8gY3JlYXRlIGEgbmV3IHVzZXIgZnJvbSBzZXNzaW9uXG4iKSk7CiAgICAgICAgICAgIHJldHVybiAwOwogICAgICAgIH0KICAgIH0KCiAgICByZXR1cm4gMTsKfQoKCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi1vLSoqKioqKgogKiBzbm1wX3Nlc3Nfb3BlbgogKgogKiBQYXJhbWV0ZXJzOgogKgkqaW5fc2Vzc2lvbgogKgogKiBSZXR1cm5zOgogKiAgICAgIFBvaW50ZXIgdG8gYSBzZXNzaW9uIGluIHRoZSBzZXNzaW9uIGxpc3QgICAtT1ItCQlGSVggLS0gcmlnaHQ/CiAqCU5VTEwgb24gZmFpbHVyZS4KICoKICogVGhlICJzcGluLWZyZWUiIHZlcnNpb24gb2Ygc25tcF9vcGVuLgogKi8Kc3RhdGljIHZvaWQgICAgKgpfc2Vzc19vcGVuKG5ldHNubXBfc2Vzc2lvbiAqIGluX3Nlc3Npb24pCnsKICAgIHN0cnVjdCBzZXNzaW9uX2xpc3QgKnNscDsKICAgIG5ldHNubXBfc2Vzc2lvbiAqc2Vzc2lvbjsKICAgIGNoYXIgICAgICAgICAgICAqY2xpZW50YWRkcl9zYXZlID0gTlVMTDsKCiAgICBpbl9zZXNzaW9uLT5zX3NubXBfZXJybm8gPSAwOwogICAgaW5fc2Vzc2lvbi0+c19lcnJubyA9IDA7CgogICAgX2luaXRfc25tcCgpOwoKICAgIGlmICgoc2xwID0gc25tcF9zZXNzX2NvcHkoaW5fc2Vzc2lvbikpID09IE5VTEwpIHsKICAgICAgICByZXR1cm4gKE5VTEwpOwogICAgfQogICAgc2Vzc2lvbiA9IHNscC0+c2Vzc2lvbjsKICAgIHNscC0+dHJhbnNwb3J0ID0gTlVMTDsKCiAgICBpZiAoTlVMTCAhPSBzZXNzaW9uLT5sb2NhbG5hbWUpIHsKICAgICAgICBjbGllbnRhZGRyX3NhdmUgPSBuZXRzbm1wX2RzX2dldF9zdHJpbmcoTkVUU05NUF9EU19MSUJSQVJZX0lELAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBORVRTTk1QX0RTX0xJQl9DTElFTlRfQUREUik7CiAgICAgICAgbmV0c25tcF9kc19zZXRfc3RyaW5nKE5FVFNOTVBfRFNfTElCUkFSWV9JRCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTkVUU05NUF9EU19MSUJfQ0xJRU5UX0FERFIsIHNlc3Npb24tPmxvY2FsbmFtZSk7CiAgICB9CgogICAgaWYgKHNlc3Npb24tPmZsYWdzICYgU05NUF9GTEFHU19TVFJFQU1fU09DS0VUKSB7CiAgICAgICAgc2xwLT50cmFuc3BvcnQgPQoJICBuZXRzbm1wX3Rkb21haW5fdHJhbnNwb3J0X2Z1bGwoInNubXAiLCBzZXNzaW9uLT5wZWVybmFtZSwKCQkJCQkgc2Vzc2lvbi0+bG9jYWxfcG9ydCwgInRjcCIsIE5VTEwpOwogICAgfSBlbHNlIHsKICAgICAgICBzbHAtPnRyYW5zcG9ydCA9CgkgIG5ldHNubXBfdGRvbWFpbl90cmFuc3BvcnRfZnVsbCgic25tcCIsIHNlc3Npb24tPnBlZXJuYW1lLAoJCQkJCSBzZXNzaW9uLT5sb2NhbF9wb3J0LCAidWRwIiwgTlVMTCk7CiAgICB9CgogICAgaWYgKE5VTEwgIT0gc2Vzc2lvbi0+bG9jYWxuYW1lKQogICAgICAgIG5ldHNubXBfZHNfc2V0X3N0cmluZyhORVRTTk1QX0RTX0xJQlJBUllfSUQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5FVFNOTVBfRFNfTElCX0NMSUVOVF9BRERSLCBjbGllbnRhZGRyX3NhdmUpOwoKICAgIGlmIChzbHAtPnRyYW5zcG9ydCA9PSBOVUxMKSB7CiAgICAgICAgREVCVUdNU0dUTCgoIl9zZXNzX29wZW4iLCAiY291bGRuJ3QgaW50ZXJwcmV0IHBlZXJuYW1lXG4iKSk7CiAgICAgICAgaW5fc2Vzc2lvbi0+c19zbm1wX2Vycm5vID0gU05NUEVSUl9CQURfQUREUkVTUzsKICAgICAgICBpbl9zZXNzaW9uLT5zX2Vycm5vID0gZXJybm87CiAgICAgICAgc25tcF9zZXRfZGV0YWlsKHNlc3Npb24tPnBlZXJuYW1lKTsKICAgICAgICBzbm1wX3Nlc3NfY2xvc2Uoc2xwKTsKICAgICAgICByZXR1cm4gTlVMTDsKICAgIH0KCiAgICBzZXNzaW9uLT5yY3ZNc2dNYXhTaXplID0gc2xwLT50cmFuc3BvcnQtPm1zZ01heFNpemU7CgogICAgaWYgKCFzbm1wdjNfZW5naW5lSURfcHJvYmUoc2xwLCBpbl9zZXNzaW9uKSkgewogICAgICAgIHNubXBfc2Vzc19jbG9zZShzbHApOwogICAgICAgIHJldHVybiBOVUxMOwogICAgfQogICAgaWYgKGNyZWF0ZV91c2VyX2Zyb21fc2Vzc2lvbihzbHAtPnNlc3Npb24pICE9IFNOTVBFUlJfU1VDQ0VTUykgewogICAgICAgIGluX3Nlc3Npb24tPnNfc25tcF9lcnJubyA9IFNOTVBFUlJfVU5LTk9XTl9VU0VSX05BTUU7ICAgICAgIC8qIFhYPz8gKi8KICAgICAgICBERUJVR01TR1RMKCgic25tcF9hcGkiLAogICAgICAgICAgICAgICAgICAgICJfc2Vzc19vcGVuKCk6IGZhaWxlZCgyKSB0byBjcmVhdGUgYSBuZXcgdXNlciBmcm9tIHNlc3Npb25cbiIpKTsKICAgICAgICBzbm1wX3Nlc3NfY2xvc2Uoc2xwKTsKICAgICAgICByZXR1cm4gTlVMTDsKICAgIH0KICAgIAogICAgc2Vzc2lvbi0+ZmxhZ3MgJj0gflNOTVBfRkxBR1NfRE9OVF9QUk9CRTsKCgogICAgcmV0dXJuICh2b2lkICopIHNscDsKfSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiBlbmQgc25tcF9zZXNzX29wZW4oKSAqLwoKCgovKgogKiBFWFRFTkRFRCBTRVNTSU9OIEFQSSAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gCiAqIAogKiBzbm1wX3Nlc3NfYWRkX2V4LCBzbm1wX3Nlc3NfYWRkLCBzbm1wX2FkZCAKICogCiAqIEFuYWxvZ291cyB0byBzbm1wX29wZW4gZmFtaWx5IG9mIGZ1bmN0aW9ucywgYnV0IHRha2luZyBhIG5ldHNubXBfdHJhbnNwb3J0CiAqIHBvaW50ZXIgYXMgYW4gZXh0cmEgYXJndW1lbnQuICBVbmxpa2Ugc25tcF9vcGVuIGV0IGFsLiBpdCBkb2Vzbid0IGF0dGVtcHQKICogdG8gaW50ZXJwcmV0IHRoZSBpbl9zZXNzaW9uLT5wZWVybmFtZSBhcyBhIHRyYW5zcG9ydCBlbmRwb2ludCBzcGVjaWZpZXIsCiAqIGJ1dCBpbnN0ZWFkIHVzZXMgdGhlIHN1cHBsaWVkIHRyYW5zcG9ydC4gIEpCUE4KICogCiAqLwoKbmV0c25tcF9zZXNzaW9uICoKc25tcF9hZGQobmV0c25tcF9zZXNzaW9uICogaW5fc2Vzc2lvbiwKICAgICAgICAgbmV0c25tcF90cmFuc3BvcnQgKnRyYW5zcG9ydCwKICAgICAgICAgaW50ICgqZnByZV9wYXJzZSkgKG5ldHNubXBfc2Vzc2lvbiAqLCBuZXRzbm1wX3RyYW5zcG9ydCAqLCB2b2lkICosCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQpLCBpbnQgKCpmcG9zdF9wYXJzZSkgKG5ldHNubXBfc2Vzc2lvbiAqLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXRzbm1wX3BkdSAqLCBpbnQpKQp7CiAgICBzdHJ1Y3Qgc2Vzc2lvbl9saXN0ICpzbHA7CiAgICBzbHAgPSAoc3RydWN0IHNlc3Npb25fbGlzdCAqKSBzbm1wX3Nlc3NfYWRkX2V4KGluX3Nlc3Npb24sIHRyYW5zcG9ydCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZnByZV9wYXJzZSwgTlVMTCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZnBvc3RfcGFyc2UsIE5VTEwsIE5VTEwsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5VTEwsIE5VTEwpOwogICAgaWYgKHNscCA9PSBOVUxMKSB7CiAgICAgICAgcmV0dXJuIE5VTEw7CiAgICB9CgogICAgc25tcF9yZXNfbG9jayhNVF9MSUJSQVJZX0lELCBNVF9MSUJfU0VTU0lPTik7CiAgICBzbHAtPm5leHQgPSBTZXNzaW9uczsKICAgIFNlc3Npb25zID0gc2xwOwogICAgc25tcF9yZXNfdW5sb2NrKE1UX0xJQlJBUllfSUQsIE1UX0xJQl9TRVNTSU9OKTsKCiAgICByZXR1cm4gKHNscC0+c2Vzc2lvbik7Cn0KCm5ldHNubXBfc2Vzc2lvbiAqCnNubXBfYWRkX2Z1bGwobmV0c25tcF9zZXNzaW9uICogaW5fc2Vzc2lvbiwKICAgICAgICAgICAgICBuZXRzbm1wX3RyYW5zcG9ydCAqdHJhbnNwb3J0LAogICAgICAgICAgICAgIGludCAoKmZwcmVfcGFyc2UpIChuZXRzbm1wX3Nlc3Npb24gKiwgbmV0c25tcF90cmFuc3BvcnQgKiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdm9pZCAqLCBpbnQpLAogICAgICAgICAgICAgIGludCAoKmZwYXJzZSkgKG5ldHNubXBfc2Vzc2lvbiAqLCBuZXRzbm1wX3BkdSAqLCB1X2NoYXIgKiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaXplX3QpLAogICAgICAgICAgICAgIGludCAoKmZwb3N0X3BhcnNlKSAobmV0c25tcF9zZXNzaW9uICosIG5ldHNubXBfcGR1ICosIGludCksCiAgICAgICAgICAgICAgaW50ICgqZmJ1aWxkKSAobmV0c25tcF9zZXNzaW9uICosIG5ldHNubXBfcGR1ICosIHVfY2hhciAqLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNpemVfdCAqKSwgaW50ICgqZnJidWlsZCkgKG5ldHNubXBfc2Vzc2lvbiAqLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldHNubXBfcGR1ICosCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdV9jaGFyICoqLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNpemVfdCAqLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNpemVfdCAqKSwKICAgICAgICAgICAgICBpbnQgKCpmY2hlY2spICh1X2NoYXIgKiwgc2l6ZV90KSwKICAgICAgICAgICAgICBuZXRzbm1wX3BkdSAqKCpmY3JlYXRlX3BkdSkgKG5ldHNubXBfdHJhbnNwb3J0ICosIHZvaWQgKiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNpemVfdCkpCnsKICAgIHN0cnVjdCBzZXNzaW9uX2xpc3QgKnNscDsKICAgIHNscCA9IChzdHJ1Y3Qgc2Vzc2lvbl9saXN0ICopIHNubXBfc2Vzc19hZGRfZXgoaW5fc2Vzc2lvbiwgdHJhbnNwb3J0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmcHJlX3BhcnNlLCBmcGFyc2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZwb3N0X3BhcnNlLCBmYnVpbGQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZyYnVpbGQsIGZjaGVjaywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmNyZWF0ZV9wZHUpOwogICAgaWYgKHNscCA9PSBOVUxMKSB7CiAgICAgICAgcmV0dXJuIE5VTEw7CiAgICB9CgogICAgc25tcF9yZXNfbG9jayhNVF9MSUJSQVJZX0lELCBNVF9MSUJfU0VTU0lPTik7CiAgICBzbHAtPm5leHQgPSBTZXNzaW9uczsKICAgIFNlc3Npb25zID0gc2xwOwogICAgc25tcF9yZXNfdW5sb2NrKE1UX0xJQlJBUllfSUQsIE1UX0xJQl9TRVNTSU9OKTsKCiAgICByZXR1cm4gKHNscC0+c2Vzc2lvbik7Cn0KCgoKdm9pZCAgICAgICAgICAgKgpzbm1wX3Nlc3NfYWRkX2V4KG5ldHNubXBfc2Vzc2lvbiAqIGluX3Nlc3Npb24sCiAgICAgICAgICAgICAgICAgbmV0c25tcF90cmFuc3BvcnQgKnRyYW5zcG9ydCwKICAgICAgICAgICAgICAgICBpbnQgKCpmcHJlX3BhcnNlKSAobmV0c25tcF9zZXNzaW9uICosIG5ldHNubXBfdHJhbnNwb3J0ICosCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZvaWQgKiwgaW50KSwKICAgICAgICAgICAgICAgICBpbnQgKCpmcGFyc2UpIChuZXRzbm1wX3Nlc3Npb24gKiwgbmV0c25tcF9wZHUgKiwgdV9jaGFyICosCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2l6ZV90KSwKICAgICAgICAgICAgICAgICBpbnQgKCpmcG9zdF9wYXJzZSkgKG5ldHNubXBfc2Vzc2lvbiAqLCBuZXRzbm1wX3BkdSAqLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50KSwKICAgICAgICAgICAgICAgICBpbnQgKCpmYnVpbGQpIChuZXRzbm1wX3Nlc3Npb24gKiwgbmV0c25tcF9wZHUgKiwgdV9jaGFyICosCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2l6ZV90ICopLAogICAgICAgICAgICAgICAgIGludCAoKmZyYnVpbGQpIChuZXRzbm1wX3Nlc3Npb24gKiwgbmV0c25tcF9wZHUgKiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdV9jaGFyICoqLCBzaXplX3QgKiwgc2l6ZV90ICopLAogICAgICAgICAgICAgICAgIGludCAoKmZjaGVjaykgKHVfY2hhciAqLCBzaXplX3QpLAogICAgICAgICAgICAgICAgIG5ldHNubXBfcGR1ICooKmZjcmVhdGVfcGR1KSAobmV0c25tcF90cmFuc3BvcnQgKiwgdm9pZCAqLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2l6ZV90KSkKewogICAgc3RydWN0IHNlc3Npb25fbGlzdCAqc2xwOwoKICAgIF9pbml0X3NubXAoKTsKCiAgICBpZiAodHJhbnNwb3J0ID09IE5VTEwpCiAgICAgICAgcmV0dXJuIE5VTEw7CgogICAgaWYgKGluX3Nlc3Npb24gPT0gTlVMTCkgewogICAgICAgIHRyYW5zcG9ydC0+Zl9jbG9zZSh0cmFuc3BvcnQpOwogICAgICAgIG5ldHNubXBfdHJhbnNwb3J0X2ZyZWUodHJhbnNwb3J0KTsKICAgICAgICByZXR1cm4gTlVMTDsKICAgIH0KCiAgICBERUJVR01TR1RMKCgic25tcF9zZXNzX2FkZCIsICJmZCAlZFxuIiwgdHJhbnNwb3J0LT5zb2NrKSk7CgogICAgaWYgKChzbHAgPSBzbm1wX3Nlc3NfY29weShpbl9zZXNzaW9uKSkgPT0gTlVMTCkgewogICAgICAgIHRyYW5zcG9ydC0+Zl9jbG9zZSh0cmFuc3BvcnQpOwogICAgICAgIG5ldHNubXBfdHJhbnNwb3J0X2ZyZWUodHJhbnNwb3J0KTsKICAgICAgICByZXR1cm4gKE5VTEwpOwogICAgfQoKICAgIHNscC0+dHJhbnNwb3J0ID0gdHJhbnNwb3J0OwogICAgc2xwLT5pbnRlcm5hbC0+aG9va19wcmUgPSBmcHJlX3BhcnNlOwogICAgc2xwLT5pbnRlcm5hbC0+aG9va19wYXJzZSA9IGZwYXJzZTsKICAgIHNscC0+aW50ZXJuYWwtPmhvb2tfcG9zdCA9IGZwb3N0X3BhcnNlOwogICAgc2xwLT5pbnRlcm5hbC0+aG9va19idWlsZCA9IGZidWlsZDsKICAgIHNscC0+aW50ZXJuYWwtPmhvb2tfcmVhbGxvY19idWlsZCA9IGZyYnVpbGQ7CiAgICBzbHAtPmludGVybmFsLT5jaGVja19wYWNrZXQgPSBmY2hlY2s7CiAgICBzbHAtPmludGVybmFsLT5ob29rX2NyZWF0ZV9wZHUgPSBmY3JlYXRlX3BkdTsKCiAgICBzbHAtPnNlc3Npb24tPnJjdk1zZ01heFNpemUgPSB0cmFuc3BvcnQtPm1zZ01heFNpemU7CgogICAgaWYgKHNscC0+c2Vzc2lvbi0+dmVyc2lvbiA9PSBTTk1QX1ZFUlNJT05fMykgewogICAgICAgIERFQlVHTVNHVEwoKCJzbm1wX3Nlc3NfYWRkIiwKICAgICAgICAgICAgICAgICAgICAiYWRkaW5nIHYzIHNlc3Npb24gLS0gZW5naW5lSUQgcHJvYmUgbm93XG4iKSk7CiAgICAgICAgaWYgKCFzbm1wdjNfZW5naW5lSURfcHJvYmUoc2xwLCBpbl9zZXNzaW9uKSkgewogICAgICAgICAgICBERUJVR01TR1RMKCgic25tcF9zZXNzX2FkZCIsICJlbmdpbmUgSUQgcHJvYmUgZmFpbGVkXG4iKSk7CiAgICAgICAgICAgIHNubXBfc2Vzc19jbG9zZShzbHApOwogICAgICAgICAgICByZXR1cm4gTlVMTDsKICAgICAgICB9CiAgICAgICAgaWYgKGNyZWF0ZV91c2VyX2Zyb21fc2Vzc2lvbihzbHAtPnNlc3Npb24pICE9IFNOTVBFUlJfU1VDQ0VTUykgewogICAgICAgICAgICBpbl9zZXNzaW9uLT5zX3NubXBfZXJybm8gPSBTTk1QRVJSX1VOS05PV05fVVNFUl9OQU1FOwogICAgICAgICAgICBERUJVR01TR1RMKCgic25tcF9hcGkiLAogICAgICAgICAgICAgICAgICAgICAgICAic25tcF9zZXNzX2FkZCgpOiBmYWlsZWQoMikgdG8gY3JlYXRlIGEgbmV3IHVzZXIgZnJvbSBzZXNzaW9uXG4iKSk7CiAgICAgICAgICAgIHNubXBfc2Vzc19jbG9zZShzbHApOwogICAgICAgICAgICByZXR1cm4gTlVMTDsKICAgICAgICB9CiAgICB9CgogICAgc2xwLT5zZXNzaW9uLT5mbGFncyAmPSB+U05NUF9GTEFHU19ET05UX1BST0JFOwoKICAgIHJldHVybiAodm9pZCAqKSBzbHA7Cn0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogIGVuZCBzbm1wX3Nlc3NfYWRkX2V4KCkgICovCgoKCnZvaWQgICAgICAgICAgICoKc25tcF9zZXNzX2FkZChuZXRzbm1wX3Nlc3Npb24gKiBpbl9zZXNzaW9uLAogICAgICAgICAgICAgIG5ldHNubXBfdHJhbnNwb3J0ICp0cmFuc3BvcnQsCiAgICAgICAgICAgICAgaW50ICgqZnByZV9wYXJzZSkgKG5ldHNubXBfc2Vzc2lvbiAqLCBuZXRzbm1wX3RyYW5zcG9ydCAqLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2b2lkICosIGludCksCiAgICAgICAgICAgICAgaW50ICgqZnBvc3RfcGFyc2UpIChuZXRzbm1wX3Nlc3Npb24gKiwgbmV0c25tcF9wZHUgKiwgaW50KSkKewogICAgcmV0dXJuIHNubXBfc2Vzc19hZGRfZXgoaW5fc2Vzc2lvbiwgdHJhbnNwb3J0LCBmcHJlX3BhcnNlLCBOVUxMLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgZnBvc3RfcGFyc2UsIE5VTEwsIE5VTEwsIE5VTEwsIE5VTEwpOwp9CgoKCnZvaWQgICAgICAgICAgICoKc25tcF9zZXNzX29wZW4obmV0c25tcF9zZXNzaW9uICogcHNzKQp7CiAgICB2b2lkICAgICAgICAgICAqcHZvaWQ7CiAgICBwdm9pZCA9IF9zZXNzX29wZW4ocHNzKTsKICAgIGlmICghcHZvaWQpIHsKICAgICAgICBTRVRfU05NUF9FUlJPUihwc3MtPnNfc25tcF9lcnJubyk7CiAgICB9CiAgICByZXR1cm4gcHZvaWQ7Cn0KCgoKLyoKICogY3JlYXRlX3VzZXJfZnJvbV9zZXNzaW9uKG5ldHNubXBfc2Vzc2lvbiAqc2Vzc2lvbik6CiAqIAogKiBjcmVhdGVzIGEgdXNlciBpbiB0aGUgdXNtIHRhYmxlIGZyb20gdGhlIGluZm9ybWF0aW9uIGluIGEgc2Vzc2lvbi4KICogSWYgdGhlIHVzZXIgYWxyZWFkeSBleGlzdHMsIGl0IGlzIHVwZGF0ZWQgd2l0aCB0aGUgY3VycmVudAogKiBpbmZvcm1hdGlvbiBmcm9tIHRoZSBzZXNzaW9uCiAqIAogKiBQYXJhbWV0ZXJzOgogKiBzZXNzaW9uIC0tIElOOiBwb2ludGVyIHRvIHRoZSBzZXNzaW9uIHRvIHVzZSB3aGVuIGNyZWF0aW5nIHRoZSB1c2VyLgogKiAKICogUmV0dXJuczoKICogU05NUEVSUl9TVUNDRVNTCiAqIFNOTVBFUlJfR0VORVJSIAogKi8KaW50CmNyZWF0ZV91c2VyX2Zyb21fc2Vzc2lvbihuZXRzbm1wX3Nlc3Npb24gKiBzZXNzaW9uKQp7CiAgICBzdHJ1Y3QgdXNtVXNlciAqdXNlcjsKICAgIGludCAgICAgICAgICAgICB1c2VyX2p1c3RfY3JlYXRlZCA9IDA7CiAgICBjaGFyICpjcDsKCiAgICAvKgogICAgICogLSBkb24ndCBjcmVhdGUtYW5vdGhlci9jb3B5LWludG8gdXNlciBmb3IgdGhpcyBzZXNzaW9uIGJ5IGRlZmF1bHQKICAgICAqIC0gYmFpbCBub3cgKG5vIGVycm9yKSBpZiB3ZSBkb24ndCBoYXZlIGFuIGVuZ2luZUlECiAgICAgKi8KICAgIGlmIChTTk1QX0ZMQUdTX1VTRVJfQ1JFQVRFRCA9PSAoc2Vzc2lvbi0+ZmxhZ3MgJiBTTk1QX0ZMQUdTX1VTRVJfQ1JFQVRFRCkgfHwKICAgICAgICBzZXNzaW9uLT5zZWN1cml0eU1vZGVsICE9IFNOTVBfU0VDX01PREVMX1VTTSB8fAogICAgICAgIHNlc3Npb24tPnZlcnNpb24gIT0gU05NUF9WRVJTSU9OXzMgfHwKICAgICAgICBzZXNzaW9uLT5zZWN1cml0eU5hbWVMZW4gPT0gMCB8fAogICAgICAgIHNlc3Npb24tPnNlY3VyaXR5RW5naW5lSURMZW4gPT0gMCkKICAgICAgICByZXR1cm4gU05NUEVSUl9TVUNDRVNTOwoKICAgIHNlc3Npb24tPmZsYWdzIHw9IFNOTVBfRkxBR1NfVVNFUl9DUkVBVEVEOwoKICAgIC8qCiAgICAgKiBub3cgdGhhdCB3ZSBoYXZlIHRoZSBlbmdpbmVJRCwgY3JlYXRlIGFuIGVudHJ5IGluIHRoZSBVU00gbGlzdAogICAgICogZm9yIHRoaXMgdXNlciB1c2luZyB0aGUgaW5mb3JtYXRpb24gaW4gdGhlIHNlc3Npb24gCiAgICAgKi8KICAgIHVzZXIgPSB1c21fZ2V0X3VzZXJfZnJvbV9saXN0KHNlc3Npb24tPnNlY3VyaXR5RW5naW5lSUQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZXNzaW9uLT5zZWN1cml0eUVuZ2luZUlETGVuLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2Vzc2lvbi0+c2VjdXJpdHlOYW1lLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdXNtX2dldF91c2VyTGlzdCgpLCAwKTsKICAgIGlmICh1c2VyID09IE5VTEwpIHsKICAgICAgICBERUJVR01TR1RMKCgic25tcF9hcGkiLCAiQnVpbGRpbmcgdXNlciAlcy4uLlxuIiwKICAgICAgICAgICAgICAgICAgICBzZXNzaW9uLT5zZWN1cml0eU5hbWUpKTsKICAgICAgICAvKgogICAgICAgICAqIHVzZXIgZG9lc24ndCBleGlzdCBzbyB3ZSBjcmVhdGUgYW5kIGFkZCBpdCAKICAgICAgICAgKi8KICAgICAgICB1c2VyID0gKHN0cnVjdCB1c21Vc2VyICopIGNhbGxvYygxLCBzaXplb2Yoc3RydWN0IHVzbVVzZXIpKTsKICAgICAgICBpZiAodXNlciA9PSBOVUxMKQogICAgICAgICAgICByZXR1cm4gU05NUEVSUl9HRU5FUlI7CgogICAgICAgIC8qCiAgICAgICAgICogY29weSBpbiB0aGUgc2VjdXJpdHlOYW1lIAogICAgICAgICAqLwogICAgICAgIGlmIChzZXNzaW9uLT5zZWN1cml0eU5hbWUpIHsKICAgICAgICAgICAgdXNlci0+bmFtZSA9IHN0cmR1cChzZXNzaW9uLT5zZWN1cml0eU5hbWUpOwogICAgICAgICAgICB1c2VyLT5zZWNOYW1lID0gc3RyZHVwKHNlc3Npb24tPnNlY3VyaXR5TmFtZSk7CiAgICAgICAgICAgIGlmICh1c2VyLT5uYW1lID09IE5VTEwgfHwgdXNlci0+c2VjTmFtZSA9PSBOVUxMKSB7CiAgICAgICAgICAgICAgICB1c21fZnJlZV91c2VyKHVzZXIpOwogICAgICAgICAgICAgICAgcmV0dXJuIFNOTVBFUlJfR0VORVJSOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICAvKgogICAgICAgICAqIGNvcHkgaW4gdGhlIGVuZ2luZUlEIAogICAgICAgICAqLwogICAgICAgIHVzZXItPmVuZ2luZUlEID0gbmV0c25tcF9tZW1kdXAoc2Vzc2lvbi0+c2VjdXJpdHlFbmdpbmVJRCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlc3Npb24tPnNlY3VyaXR5RW5naW5lSURMZW4pOwogICAgICAgIGlmICghdXNlci0+ZW5naW5lSUQpIHsKICAgICAgICAgICAgdXNtX2ZyZWVfdXNlcih1c2VyKTsKICAgICAgICAgICAgcmV0dXJuIFNOTVBFUlJfR0VORVJSOwogICAgICAgIH0KICAgICAgICB1c2VyLT5lbmdpbmVJRExlbiA9IHNlc3Npb24tPnNlY3VyaXR5RW5naW5lSURMZW47CgogICAgICAgIHVzZXJfanVzdF9jcmVhdGVkID0gMTsKICAgIH0KCiAgICAvKgogICAgICogY29weSB0aGUgYXV0aCBwcm90b2NvbCAKICAgICAqLwogICAgaWYgKHVzZXItPmF1dGhQcm90b2NvbCA9PSBOVUxMICYmIHNlc3Npb24tPnNlY3VyaXR5QXV0aFByb3RvICE9IE5VTEwpIHsKICAgICAgICBTTk1QX0ZSRUUodXNlci0+YXV0aFByb3RvY29sKTsKICAgICAgICB1c2VyLT5hdXRoUHJvdG9jb2wgPQogICAgICAgICAgICBzbm1wX2R1cGxpY2F0ZV9vYmppZChzZXNzaW9uLT5zZWN1cml0eUF1dGhQcm90bywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2Vzc2lvbi0+c2VjdXJpdHlBdXRoUHJvdG9MZW4pOwogICAgICAgIGlmICh1c2VyLT5hdXRoUHJvdG9jb2wgPT0gTlVMTCkgewogICAgICAgICAgICB1c21fZnJlZV91c2VyKHVzZXIpOwogICAgICAgICAgICByZXR1cm4gU05NUEVSUl9HRU5FUlI7CiAgICAgICAgfQogICAgICAgIHVzZXItPmF1dGhQcm90b2NvbExlbiA9IHNlc3Npb24tPnNlY3VyaXR5QXV0aFByb3RvTGVuOwogICAgfQoKICAgIC8qCiAgICAgKiBjb3B5IHRoZSBwcml2IHByb3RvY29sIAogICAgICovCiAgICBpZiAodXNlci0+cHJpdlByb3RvY29sID09IE5VTEwgJiYgc2Vzc2lvbi0+c2VjdXJpdHlQcml2UHJvdG8gIT0gTlVMTCkgewogICAgICAgIFNOTVBfRlJFRSh1c2VyLT5wcml2UHJvdG9jb2wpOwogICAgICAgIHVzZXItPnByaXZQcm90b2NvbCA9CiAgICAgICAgICAgIHNubXBfZHVwbGljYXRlX29iamlkKHNlc3Npb24tPnNlY3VyaXR5UHJpdlByb3RvLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZXNzaW9uLT5zZWN1cml0eVByaXZQcm90b0xlbik7CiAgICAgICAgaWYgKHVzZXItPnByaXZQcm90b2NvbCA9PSBOVUxMKSB7CiAgICAgICAgICAgIHVzbV9mcmVlX3VzZXIodXNlcik7CiAgICAgICAgICAgIHJldHVybiBTTk1QRVJSX0dFTkVSUjsKICAgICAgICB9CiAgICAgICAgdXNlci0+cHJpdlByb3RvY29sTGVuID0gc2Vzc2lvbi0+c2VjdXJpdHlQcml2UHJvdG9MZW47CiAgICB9CgogICAgLyoKICAgICAqIGNvcHkgaW4gdGhlIGF1dGhlbnRpY2F0aW9uIEtleS4gIElmIG5vdCBsb2NhbGl6ZWQsIGxvY2FsaXplIGl0IAogICAgICovCiAgICBpZiAodXNlci0+YXV0aEtleSA9PSBOVUxMKSB7CiAgICAgICAgaWYgKHNlc3Npb24tPnNlY3VyaXR5QXV0aExvY2FsS2V5ICE9IE5VTEwKICAgICAgICAgICAgJiYgc2Vzc2lvbi0+c2VjdXJpdHlBdXRoTG9jYWxLZXlMZW4gIT0gMCkgewogICAgICAgICAgICAvKiBhbHJlYWR5IGxvY2FsaXplZCBrZXkgcGFzc2VkIGluLiAgdXNlIGl0ICovCiAgICAgICAgICAgIFNOTVBfRlJFRSh1c2VyLT5hdXRoS2V5KTsKICAgICAgICAgICAgdXNlci0+YXV0aEtleSA9IG5ldHNubXBfbWVtZHVwKHNlc3Npb24tPnNlY3VyaXR5QXV0aExvY2FsS2V5LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2Vzc2lvbi0+c2VjdXJpdHlBdXRoTG9jYWxLZXlMZW4pOwogICAgICAgICAgICBpZiAoIXVzZXItPmF1dGhLZXkpIHsKICAgICAgICAgICAgICAgIHVzbV9mcmVlX3VzZXIodXNlcik7CiAgICAgICAgICAgICAgICByZXR1cm4gU05NUEVSUl9HRU5FUlI7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgdXNlci0+YXV0aEtleUxlbiA9IHNlc3Npb24tPnNlY3VyaXR5QXV0aExvY2FsS2V5TGVuOwogICAgICAgIH0gZWxzZSBpZiAoc2Vzc2lvbi0+c2VjdXJpdHlBdXRoS2V5ICE9IE5VTEwKICAgICAgICAgICAgICAgICAgICYmIHNlc3Npb24tPnNlY3VyaXR5QXV0aEtleUxlbiAhPSAwKSB7CiAgICAgICAgICAgIFNOTVBfRlJFRSh1c2VyLT5hdXRoS2V5KTsKICAgICAgICAgICAgdXNlci0+YXV0aEtleSA9ICh1X2NoYXIgKikgY2FsbG9jKDEsIFVTTV9MRU5HVEhfS1VfSEFTSEJMT0NLKTsKICAgICAgICAgICAgaWYgKHVzZXItPmF1dGhLZXkgPT0gTlVMTCkgewogICAgICAgICAgICAgICAgdXNtX2ZyZWVfdXNlcih1c2VyKTsKICAgICAgICAgICAgICAgIHJldHVybiBTTk1QRVJSX0dFTkVSUjsKICAgICAgICAgICAgfQogICAgICAgICAgICB1c2VyLT5hdXRoS2V5TGVuID0gVVNNX0xFTkdUSF9LVV9IQVNIQkxPQ0s7CiAgICAgICAgICAgIGlmIChnZW5lcmF0ZV9rdWwodXNlci0+YXV0aFByb3RvY29sLCB1c2VyLT5hdXRoUHJvdG9jb2xMZW4sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2Vzc2lvbi0+c2VjdXJpdHlFbmdpbmVJRCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZXNzaW9uLT5zZWN1cml0eUVuZ2luZUlETGVuLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlc3Npb24tPnNlY3VyaXR5QXV0aEtleSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZXNzaW9uLT5zZWN1cml0eUF1dGhLZXlMZW4sIHVzZXItPmF1dGhLZXksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJnVzZXItPmF1dGhLZXlMZW4pICE9IFNOTVBFUlJfU1VDQ0VTUykgewogICAgICAgICAgICAgICAgdXNtX2ZyZWVfdXNlcih1c2VyKTsKICAgICAgICAgICAgICAgIHJldHVybiBTTk1QRVJSX0dFTkVSUjsKICAgICAgICAgICAgfQogICAgICAgIH0gZWxzZSBpZiAoKGNwID0gbmV0c25tcF9kc19nZXRfc3RyaW5nKE5FVFNOTVBfRFNfTElCUkFSWV9JRCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTkVUU05NUF9EU19MSUJfQVVUSExPQ0FMSVpFREtFWSkpKSB7CiAgICAgICAgICAgIHNpemVfdCBidWZsZW4gPSBVU01fQVVUSF9LVV9MRU47CiAgICAgICAgICAgIFNOTVBfRlJFRSh1c2VyLT5hdXRoS2V5KTsKICAgICAgICAgICAgdXNlci0+YXV0aEtleSA9ICh1X2NoYXIgKiltYWxsb2MoYnVmbGVuKTsgLyogbWF4IGxlbmd0aCBuZWVkZWQgKi8KICAgICAgICAgICAgdXNlci0+YXV0aEtleUxlbiA9IDA7CiAgICAgICAgICAgIC8qIGl0IHdpbGwgYmUgYSBoZXggc3RyaW5nICovCiAgICAgICAgICAgIGlmICghc25tcF9oZXhfdG9fYmluYXJ5KCZ1c2VyLT5hdXRoS2V5LCAmYnVmbGVuLCAmdXNlci0+YXV0aEtleUxlbiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMCwgY3ApKSB7CiAgICAgICAgICAgICAgICB1c21fZnJlZV91c2VyKHVzZXIpOwogICAgICAgICAgICAgICAgcmV0dXJuIFNOTVBFUlJfR0VORVJSOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQoKICAgIC8qCiAgICAgKiBjb3B5IGluIHRoZSBwcml2YWN5IEtleS4gIElmIG5vdCBsb2NhbGl6ZWQsIGxvY2FsaXplIGl0IAogICAgICovCiAgICBpZiAodXNlci0+cHJpdktleSA9PSBOVUxMKSB7CiAgICAgICAgaWYgKHNlc3Npb24tPnNlY3VyaXR5UHJpdkxvY2FsS2V5ICE9IE5VTEwKICAgICAgICAgICAgJiYgc2Vzc2lvbi0+c2VjdXJpdHlQcml2TG9jYWxLZXlMZW4gIT0gMCkgewogICAgICAgICAgICAvKiBhbHJlYWR5IGxvY2FsaXplZCBrZXkgcGFzc2VkIGluLiAgdXNlIGl0ICovCiAgICAgICAgICAgIFNOTVBfRlJFRSh1c2VyLT5wcml2S2V5KTsKICAgICAgICAgICAgdXNlci0+cHJpdktleSA9IG5ldHNubXBfbWVtZHVwKHNlc3Npb24tPnNlY3VyaXR5UHJpdkxvY2FsS2V5LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2Vzc2lvbi0+c2VjdXJpdHlQcml2TG9jYWxLZXlMZW4pOwogICAgICAgICAgICBpZiAoIXVzZXItPnByaXZLZXkpIHsKICAgICAgICAgICAgICAgIHVzbV9mcmVlX3VzZXIodXNlcik7CiAgICAgICAgICAgICAgICByZXR1cm4gU05NUEVSUl9HRU5FUlI7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgdXNlci0+cHJpdktleUxlbiA9IHNlc3Npb24tPnNlY3VyaXR5UHJpdkxvY2FsS2V5TGVuOwogICAgICAgIH0gZWxzZSBpZiAoc2Vzc2lvbi0+c2VjdXJpdHlQcml2S2V5ICE9IE5VTEwKICAgICAgICAgICAgICAgICAgICYmIHNlc3Npb24tPnNlY3VyaXR5UHJpdktleUxlbiAhPSAwKSB7CiAgICAgICAgICAgIFNOTVBfRlJFRSh1c2VyLT5wcml2S2V5KTsKICAgICAgICAgICAgdXNlci0+cHJpdktleSA9ICh1X2NoYXIgKikgY2FsbG9jKDEsIFVTTV9MRU5HVEhfS1VfSEFTSEJMT0NLKTsKICAgICAgICAgICAgaWYgKHVzZXItPnByaXZLZXkgPT0gTlVMTCkgewogICAgICAgICAgICAgICAgdXNtX2ZyZWVfdXNlcih1c2VyKTsKICAgICAgICAgICAgICAgIHJldHVybiBTTk1QRVJSX0dFTkVSUjsKICAgICAgICAgICAgfQogICAgICAgICAgICB1c2VyLT5wcml2S2V5TGVuID0gVVNNX0xFTkdUSF9LVV9IQVNIQkxPQ0s7CiAgICAgICAgICAgIGlmIChnZW5lcmF0ZV9rdWwodXNlci0+YXV0aFByb3RvY29sLCB1c2VyLT5hdXRoUHJvdG9jb2xMZW4sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2Vzc2lvbi0+c2VjdXJpdHlFbmdpbmVJRCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZXNzaW9uLT5zZWN1cml0eUVuZ2luZUlETGVuLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlc3Npb24tPnNlY3VyaXR5UHJpdktleSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZXNzaW9uLT5zZWN1cml0eVByaXZLZXlMZW4sIHVzZXItPnByaXZLZXksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJnVzZXItPnByaXZLZXlMZW4pICE9IFNOTVBFUlJfU1VDQ0VTUykgewogICAgICAgICAgICAgICAgdXNtX2ZyZWVfdXNlcih1c2VyKTsKICAgICAgICAgICAgICAgIHJldHVybiBTTk1QRVJSX0dFTkVSUjsKICAgICAgICAgICAgfQogICAgICAgIH0gZWxzZSBpZiAoKGNwID0gbmV0c25tcF9kc19nZXRfc3RyaW5nKE5FVFNOTVBfRFNfTElCUkFSWV9JRCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTkVUU05NUF9EU19MSUJfUFJJVkxPQ0FMSVpFREtFWSkpKSB7CiAgICAgICAgICAgIHNpemVfdCBidWZsZW4gPSBVU01fUFJJVl9LVV9MRU47CiAgICAgICAgICAgIFNOTVBfRlJFRSh1c2VyLT5wcml2S2V5KTsKICAgICAgICAgICAgdXNlci0+cHJpdktleSA9ICh1X2NoYXIgKiltYWxsb2MoYnVmbGVuKTsgLyogbWF4IGxlbmd0aCBuZWVkZWQgKi8KICAgICAgICAgICAgdXNlci0+cHJpdktleUxlbiA9IDA7CiAgICAgICAgICAgIC8qIGl0IHdpbGwgYmUgYSBoZXggc3RyaW5nICovCiAgICAgICAgICAgIGlmICghc25tcF9oZXhfdG9fYmluYXJ5KCZ1c2VyLT5wcml2S2V5LCAmYnVmbGVuLCAmdXNlci0+cHJpdktleUxlbiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMCwgY3ApKSB7CiAgICAgICAgICAgICAgICB1c21fZnJlZV91c2VyKHVzZXIpOwogICAgICAgICAgICAgICAgcmV0dXJuIFNOTVBFUlJfR0VORVJSOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQoKICAgIGlmICh1c2VyX2p1c3RfY3JlYXRlZCkgewogICAgICAgIC8qCiAgICAgICAgICogYWRkIHRoZSB1c2VyIGludG8gdGhlIGRhdGFiYXNlIAogICAgICAgICAqLwogICAgICAgIHVzZXItPnVzZXJTdGF0dXMgPSBSU19BQ1RJVkU7CiAgICAgICAgdXNlci0+dXNlclN0b3JhZ2VUeXBlID0gU1RfUkVBRE9OTFk7CiAgICAgICAgdXNtX2FkZF91c2VyKHVzZXIpOwogICAgfQoKICAgIHJldHVybiBTTk1QRVJSX1NVQ0NFU1M7CgoKfSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiBlbmQgY3JlYXRlX3VzZXJfZnJvbV9zZXNzaW9uKCkgKi8KCi8qCiAqICBEbyBhICJkZWVwIGZyZWUoKSIgb2YgYSBuZXRzbm1wX3Nlc3Npb24uCiAqCiAqICBDQVVUSU9OOiAgU0hPVUxEIE9OTFkgQkUgVVNFRCBGUk9NIHNubXBfc2Vzc19jbG9zZSgpIE9SIFNJTUlMQVIuCiAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGhlbmNlIGl0IGlzIHN0YXRpYykKICovCgpzdGF0aWMgdm9pZApzbm1wX2ZyZWVfc2Vzc2lvbihuZXRzbm1wX3Nlc3Npb24gKiBzKQp7CiAgICBpZiAocykgewogICAgICAgIFNOTVBfRlJFRShzLT5sb2NhbG5hbWUpOwogICAgICAgIFNOTVBfRlJFRShzLT5wZWVybmFtZSk7CiAgICAgICAgU05NUF9GUkVFKHMtPmNvbW11bml0eSk7CiAgICAgICAgU05NUF9GUkVFKHMtPmNvbnRleHRFbmdpbmVJRCk7CiAgICAgICAgU05NUF9GUkVFKHMtPmNvbnRleHROYW1lKTsKICAgICAgICBTTk1QX0ZSRUUocy0+c2VjdXJpdHlFbmdpbmVJRCk7CiAgICAgICAgU05NUF9GUkVFKHMtPnNlY3VyaXR5TmFtZSk7CiAgICAgICAgU05NUF9GUkVFKHMtPnNlY3VyaXR5QXV0aFByb3RvKTsKICAgICAgICBTTk1QX0ZSRUUocy0+c2VjdXJpdHlQcml2UHJvdG8pOwogICAgICAgIFNOTVBfRlJFRShzLT5wYXJhbU5hbWUpOwoKICAgICAgICAvKgogICAgICAgICAqIGNsZWFyIHNlc3Npb24gZnJvbSBhbnkgY2FsbGJhY2tzCiAgICAgICAgICovCiAgICAgICAgbmV0c25tcF9jYWxsYmFja19jbGVhcl9jbGllbnRfYXJnKHMsIDAsIDApOwoKICAgICAgICBmcmVlKChjaGFyICopIHMpOwogICAgfQp9CgovKgogKiBDbG9zZSB0aGUgaW5wdXQgc2Vzc2lvbi4gIEZyZWVzIGFsbCBkYXRhIGFsbG9jYXRlZCBmb3IgdGhlIHNlc3Npb24sCiAqIGRlcXVldWVzIGFueSBwZW5kaW5nIHJlcXVlc3RzLCBhbmQgY2xvc2VzIGFueSBzb2NrZXRzIGFsbG9jYXRlZCBmb3IKICogdGhlIHNlc3Npb24uICBSZXR1cm5zIDAgb24gZXJyb3IsIDEgb3RoZXJ3aXNlLgogKi8KaW50CnNubXBfc2Vzc19jbG9zZSh2b2lkICpzZXNzcCkKewogICAgc3RydWN0IHNlc3Npb25fbGlzdCAqc2xwID0gKHN0cnVjdCBzZXNzaW9uX2xpc3QgKikgc2Vzc3A7CiAgICBuZXRzbm1wX3RyYW5zcG9ydCAqdHJhbnNwb3J0OwogICAgc3RydWN0IHNubXBfaW50ZXJuYWxfc2Vzc2lvbiAqaXNwOwogICAgbmV0c25tcF9zZXNzaW9uICpzZXNwID0gTlVMTDsKICAgIHN0cnVjdCBzbm1wX3NlY21vZF9kZWYgKnNwdHI7CgogICAgaWYgKHNscCA9PSBOVUxMKSB7CiAgICAgICAgcmV0dXJuIDA7CiAgICB9CgogICAgaWYgKHNscC0+c2Vzc2lvbiAhPSBOVUxMICYmCiAgICAgICAgKHNwdHIgPSBmaW5kX3NlY19tb2Qoc2xwLT5zZXNzaW9uLT5zZWN1cml0eU1vZGVsKSkgIT0gTlVMTCAmJgogICAgICAgIHNwdHItPnNlc3Npb25fY2xvc2UgIT0gTlVMTCkgewogICAgICAgICgqc3B0ci0+c2Vzc2lvbl9jbG9zZSkgKHNscC0+c2Vzc2lvbik7CiAgICB9CgogICAgaXNwID0gc2xwLT5pbnRlcm5hbDsKICAgIHNscC0+aW50ZXJuYWwgPSAwOwoKICAgIGlmIChpc3ApIHsKICAgICAgICBuZXRzbm1wX3JlcXVlc3RfbGlzdCAqcnAsICpvcnA7CgogICAgICAgIFNOTVBfRlJFRShpc3AtPnBhY2tldCk7CgogICAgICAgIC8qCiAgICAgICAgICogRnJlZSBlYWNoIGVsZW1lbnQgaW4gdGhlIGlucHV0IHJlcXVlc3QgbGlzdC4gIAogICAgICAgICAqLwogICAgICAgIHJwID0gaXNwLT5yZXF1ZXN0czsKICAgICAgICB3aGlsZSAocnApIHsKICAgICAgICAgICAgb3JwID0gcnA7CiAgICAgICAgICAgIHJwID0gcnAtPm5leHRfcmVxdWVzdDsKICAgICAgICAgICAgaWYgKG9ycC0+Y2FsbGJhY2spIHsKICAgICAgICAgICAgICAgIG9ycC0+Y2FsbGJhY2soTkVUU05NUF9DQUxMQkFDS19PUF9USU1FRF9PVVQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNscC0+c2Vzc2lvbiwgb3JwLT5wZHUtPnJlcWlkLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvcnAtPnBkdSwgb3JwLT5jYl9kYXRhKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBzbm1wX2ZyZWVfcGR1KG9ycC0+cGR1KTsKICAgICAgICAgICAgZnJlZSgoY2hhciAqKSBvcnApOwogICAgICAgIH0KCiAgICAgICAgZnJlZSgoY2hhciAqKSBpc3ApOwogICAgfQoKICAgIHRyYW5zcG9ydCA9IHNscC0+dHJhbnNwb3J0OwogICAgc2xwLT50cmFuc3BvcnQgPSAwOwoKICAgIGlmICh0cmFuc3BvcnQpIHsKICAgICAgICB0cmFuc3BvcnQtPmZfY2xvc2UodHJhbnNwb3J0KTsKICAgICAgICBuZXRzbm1wX3RyYW5zcG9ydF9mcmVlKHRyYW5zcG9ydCk7CiAgICB9CgogICAgc2VzcCA9IHNscC0+c2Vzc2lvbjsKICAgIHNscC0+c2Vzc2lvbiA9IDA7CgogICAgLyoKICAgICAqIFRoZSBmb2xsb3dpbmcgaXMgbmVjZXNzYXJ5IHRvIGF2b2lkIG1lbW9yeSBsZWFrYWdlIHdoZW4gY2xvc2luZyBBZ2VudFggCiAgICAgKiBzZXNzaW9ucyB0aGF0IG1heSBoYXZlIG11bHRpcGxlIHN1YnNlc3Npb25zLiAgVGhlc2UgaGFuZyBvZmYgdGhlIG1haW4KICAgICAqIHNlc3Npb24gYXQgLT5zdWJzZXNzaW9uLCBhbmQgY2hhaW4gdGhyb3VnaCAtPm5leHQuICAKICAgICAqLwoKICAgIGlmIChzZXNwICE9IE5VTEwgJiYgc2VzcC0+c3Vic2Vzc2lvbiAhPSBOVUxMKSB7CiAgICAgICAgbmV0c25tcF9zZXNzaW9uICpzdWJzZXNzaW9uID0gc2VzcC0+c3Vic2Vzc2lvbiwgKnRtcHN1YjsKCiAgICAgICAgd2hpbGUgKHN1YnNlc3Npb24gIT0gTlVMTCkgewogICAgICAgICAgICBERUJVR01TR1RMKCgic25tcF9zZXNzX2Nsb3NlIiwKICAgICAgICAgICAgICAgICAgICAgICAgImNsb3Npbmcgc2Vzc2lvbiAlcCwgc3Vic2Vzc2lvbiAlcFxuIiwgc2VzcCwKICAgICAgICAgICAgICAgICAgICAgICAgc3Vic2Vzc2lvbikpOwogICAgICAgICAgICB0bXBzdWIgPSBzdWJzZXNzaW9uLT5uZXh0OwogICAgICAgICAgICBzbm1wX2ZyZWVfc2Vzc2lvbihzdWJzZXNzaW9uKTsKICAgICAgICAgICAgc3Vic2Vzc2lvbiA9IHRtcHN1YjsKICAgICAgICB9CiAgICB9CgogICAgc25tcF9mcmVlX3Nlc3Npb24oc2VzcCk7CiAgICBmcmVlKChjaGFyICopIHNscCk7CiAgICByZXR1cm4gMTsKfQoKaW50CnNubXBfY2xvc2UobmV0c25tcF9zZXNzaW9uICogc2Vzc2lvbikKewogICAgc3RydWN0IHNlc3Npb25fbGlzdCAqc2xwID0gTlVMTCwgKm9zbHAgPSBOVUxMOwoKICAgIHsgICAgICAgICAgICAgICAgICAgICAgICAgICAvKk1UQ1JJVElDQUxfUkVTT1VSQ0UgKi8KICAgICAgICBzbm1wX3Jlc19sb2NrKE1UX0xJQlJBUllfSUQsIE1UX0xJQl9TRVNTSU9OKTsKICAgICAgICBpZiAoU2Vzc2lvbnMgJiYgU2Vzc2lvbnMtPnNlc3Npb24gPT0gc2Vzc2lvbikgeyAvKiBJZiBmaXJzdCBlbnRyeSAqLwogICAgICAgICAgICBzbHAgPSBTZXNzaW9uczsKICAgICAgICAgICAgU2Vzc2lvbnMgPSBzbHAtPm5leHQ7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZm9yIChzbHAgPSBTZXNzaW9uczsgc2xwOyBzbHAgPSBzbHAtPm5leHQpIHsKICAgICAgICAgICAgICAgIGlmIChzbHAtPnNlc3Npb24gPT0gc2Vzc2lvbikgewogICAgICAgICAgICAgICAgICAgIGlmIChvc2xwKSAgIC8qIGlmIHdlIGZvdW5kIGVudHJ5IHRoYXQgcG9pbnRzIGhlcmUgKi8KICAgICAgICAgICAgICAgICAgICAgICAgb3NscC0+bmV4dCA9IHNscC0+bmV4dDsgLyogbGluayBhcm91bmQgdGhpcyBlbnRyeSAqLwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgb3NscCA9IHNscDsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBzbm1wX3Jlc191bmxvY2soTVRfTElCUkFSWV9JRCwgTVRfTElCX1NFU1NJT04pOwogICAgfSAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qRU5EIE1UQ1JJVElDQUxfUkVTT1VSQ0UgKi8KICAgIGlmIChzbHAgPT0gTlVMTCkgewogICAgICAgIHJldHVybiAwOwogICAgfQogICAgcmV0dXJuIHNubXBfc2Vzc19jbG9zZSgodm9pZCAqKSBzbHApOwp9CgppbnQKc25tcF9jbG9zZV9zZXNzaW9ucyh2b2lkKQp7CiAgICBzdHJ1Y3Qgc2Vzc2lvbl9saXN0ICpzbHA7CgogICAgc25tcF9yZXNfbG9jayhNVF9MSUJSQVJZX0lELCBNVF9MSUJfU0VTU0lPTik7CiAgICB3aGlsZSAoU2Vzc2lvbnMpIHsKICAgICAgICBzbHAgPSBTZXNzaW9uczsKICAgICAgICBTZXNzaW9ucyA9IFNlc3Npb25zLT5uZXh0OwogICAgICAgIHNubXBfc2Vzc19jbG9zZSgodm9pZCAqKSBzbHApOwogICAgfQogICAgc25tcF9yZXNfdW5sb2NrKE1UX0xJQlJBUllfSUQsIE1UX0xJQl9TRVNTSU9OKTsKICAgIHJldHVybiAxOwp9CgpzdGF0aWMgaW50CnNubXB2M19idWlsZF9wcm9iZV9wZHUobmV0c25tcF9wZHUgKipwZHUpCnsKICAgIHN0cnVjdCB1c21Vc2VyICp1c2VyOwoKICAgIC8qCiAgICAgKiBjcmVhdGUgdGhlIHBkdSAKICAgICAqLwogICAgaWYgKCFwZHUpCiAgICAgICAgcmV0dXJuIC0xOwogICAgKnBkdSA9IHNubXBfcGR1X2NyZWF0ZShTTk1QX01TR19HRVQpOwogICAgaWYgKCEoKnBkdSkpCiAgICAgICAgcmV0dXJuIC0xOwogICAgKCpwZHUpLT52ZXJzaW9uID0gU05NUF9WRVJTSU9OXzM7CiAgICAoKnBkdSktPnNlY3VyaXR5TmFtZSA9IHN0cmR1cCgiIik7CiAgICAoKnBkdSktPnNlY3VyaXR5TmFtZUxlbiA9IHN0cmxlbigoKnBkdSktPnNlY3VyaXR5TmFtZSk7CiAgICAoKnBkdSktPnNlY3VyaXR5TGV2ZWwgPSBTTk1QX1NFQ19MRVZFTF9OT0FVVEg7CiAgICAoKnBkdSktPnNlY3VyaXR5TW9kZWwgPSBTTk1QX1NFQ19NT0RFTF9VU007CgogICAgLyoKICAgICAqIGNyZWF0ZSB0aGUgZW1wdHkgdXNlciAKICAgICAqLwogICAgdXNlciA9IHVzbV9nZXRfdXNlcihOVUxMLCAwLCAoKnBkdSktPnNlY3VyaXR5TmFtZSk7CiAgICBpZiAodXNlciA9PSBOVUxMKSB7CiAgICAgICAgdXNlciA9IChzdHJ1Y3QgdXNtVXNlciAqKSBjYWxsb2MoMSwgc2l6ZW9mKHN0cnVjdCB1c21Vc2VyKSk7CiAgICAgICAgaWYgKHVzZXIgPT0gTlVMTCkgewogICAgICAgICAgICBzbm1wX2ZyZWVfcGR1KCpwZHUpOwogICAgICAgICAgICAqcGR1ID0gKG5ldHNubXBfcGR1ICopIE5VTEw7CiAgICAgICAgICAgIHJldHVybiAtMTsKICAgICAgICB9CiAgICAgICAgdXNlci0+bmFtZSA9IHN0cmR1cCgoKnBkdSktPnNlY3VyaXR5TmFtZSk7CiAgICAgICAgdXNlci0+c2VjTmFtZSA9IHN0cmR1cCgoKnBkdSktPnNlY3VyaXR5TmFtZSk7CiAgICAgICAgdXNlci0+YXV0aFByb3RvY29sTGVuID0gc2l6ZW9mKHVzbU5vQXV0aFByb3RvY29sKSAvIHNpemVvZihvaWQpOwogICAgICAgIHVzZXItPmF1dGhQcm90b2NvbCA9CiAgICAgICAgICAgIHNubXBfZHVwbGljYXRlX29iamlkKHVzbU5vQXV0aFByb3RvY29sLCB1c2VyLT5hdXRoUHJvdG9jb2xMZW4pOwogICAgICAgIHVzZXItPnByaXZQcm90b2NvbExlbiA9IHNpemVvZih1c21Ob1ByaXZQcm90b2NvbCkgLyBzaXplb2Yob2lkKTsKICAgICAgICB1c2VyLT5wcml2UHJvdG9jb2wgPQogICAgICAgICAgICBzbm1wX2R1cGxpY2F0ZV9vYmppZCh1c21Ob1ByaXZQcm90b2NvbCwgdXNlci0+cHJpdlByb3RvY29sTGVuKTsKICAgICAgICB1c21fYWRkX3VzZXIodXNlcik7CiAgICB9CiAgICByZXR1cm4gMDsKfQoKc3RhdGljIHZvaWQKc25tcHYzX2NhbGNfbXNnX2ZsYWdzKGludCBzZWNfbGV2ZWwsIGludCBtc2dfY29tbWFuZCwgdV9jaGFyICogZmxhZ3MpCnsKICAgICpmbGFncyA9IDA7CiAgICBpZiAoc2VjX2xldmVsID09IFNOTVBfU0VDX0xFVkVMX0FVVEhOT1BSSVYpCiAgICAgICAgKmZsYWdzID0gU05NUF9NU0dfRkxBR19BVVRIX0JJVDsKICAgIGVsc2UgaWYgKHNlY19sZXZlbCA9PSBTTk1QX1NFQ19MRVZFTF9BVVRIUFJJVikKICAgICAgICAqZmxhZ3MgPSBTTk1QX01TR19GTEFHX0FVVEhfQklUIHwgU05NUF9NU0dfRkxBR19QUklWX0JJVDsKCiAgICBpZiAoU05NUF9DTURfQ09ORklSTUVEKG1zZ19jb21tYW5kKSkKICAgICAgICAqZmxhZ3MgfD0gU05NUF9NU0dfRkxBR19SUFJUX0JJVDsKCiAgICByZXR1cm47Cn0KCnN0YXRpYyBpbnQKc25tcHYzX3ZlcmlmeV9tc2cobmV0c25tcF9yZXF1ZXN0X2xpc3QgKnJwLCBuZXRzbm1wX3BkdSAqcGR1KQp7CiAgICBuZXRzbm1wX3BkdSAgICAqcnBkdTsKCiAgICBpZiAoIXJwIHx8ICFycC0+cGR1IHx8ICFwZHUpCiAgICAgICAgcmV0dXJuIDA7CiAgICAvKgogICAgICogUmVwb3J0cyBkb24ndCBoYXZlIHRvIG1hdGNoIGFueXRoaW5nIGFjY29yZGluZyB0byB0aGUgc3BlYyAKICAgICAqLwogICAgaWYgKHBkdS0+Y29tbWFuZCA9PSBTTk1QX01TR19SRVBPUlQpCiAgICAgICAgcmV0dXJuIDE7CiAgICBycGR1ID0gcnAtPnBkdTsKICAgIGlmIChycC0+cmVxdWVzdF9pZCAhPSBwZHUtPnJlcWlkIHx8IHJwZHUtPnJlcWlkICE9IHBkdS0+cmVxaWQpCiAgICAgICAgcmV0dXJuIDA7CiAgICBpZiAocnBkdS0+dmVyc2lvbiAhPSBwZHUtPnZlcnNpb24pCiAgICAgICAgcmV0dXJuIDA7CiAgICBpZiAocnBkdS0+c2VjdXJpdHlNb2RlbCAhPSBwZHUtPnNlY3VyaXR5TW9kZWwpCiAgICAgICAgcmV0dXJuIDA7CiAgICBpZiAocnBkdS0+c2VjdXJpdHlMZXZlbCAhPSBwZHUtPnNlY3VyaXR5TGV2ZWwpCiAgICAgICAgcmV0dXJuIDA7CgogICAgaWYgKHJwZHUtPmNvbnRleHRFbmdpbmVJRExlbiAhPSBwZHUtPmNvbnRleHRFbmdpbmVJRExlbiB8fAogICAgICAgIG1lbWNtcChycGR1LT5jb250ZXh0RW5naW5lSUQsIHBkdS0+Y29udGV4dEVuZ2luZUlELAogICAgICAgICAgICAgICBwZHUtPmNvbnRleHRFbmdpbmVJRExlbikpCiAgICAgICAgcmV0dXJuIDA7CiAgICBpZiAocnBkdS0+Y29udGV4dE5hbWVMZW4gIT0gcGR1LT5jb250ZXh0TmFtZUxlbiB8fAogICAgICAgIG1lbWNtcChycGR1LT5jb250ZXh0TmFtZSwgcGR1LT5jb250ZXh0TmFtZSwgcGR1LT5jb250ZXh0TmFtZUxlbikpCiAgICAgICAgcmV0dXJuIDA7CiAgICBpZiAocnBkdS0+c2VjdXJpdHlFbmdpbmVJRExlbiAhPSBwZHUtPnNlY3VyaXR5RW5naW5lSURMZW4gfHwKICAgICAgICBtZW1jbXAocnBkdS0+c2VjdXJpdHlFbmdpbmVJRCwgcGR1LT5zZWN1cml0eUVuZ2luZUlELAogICAgICAgICAgICAgICBwZHUtPnNlY3VyaXR5RW5naW5lSURMZW4pKQogICAgICAgIHJldHVybiAwOwogICAgaWYgKHJwZHUtPnNlY3VyaXR5TmFtZUxlbiAhPSBwZHUtPnNlY3VyaXR5TmFtZUxlbiB8fAogICAgICAgIG1lbWNtcChycGR1LT5zZWN1cml0eU5hbWUsIHBkdS0+c2VjdXJpdHlOYW1lLAogICAgICAgICAgICAgICBwZHUtPnNlY3VyaXR5TmFtZUxlbikpCiAgICAgICAgcmV0dXJuIDA7CiAgICByZXR1cm4gMTsKfQoKCi8qCiAqIFNOTVB2MwogKiAqIFRha2VzIGEgc2Vzc2lvbiBhbmQgYSBwZHUgYW5kIHNlcmlhbGl6ZXMgdGhlIEFTTiBQRFUgaW50byB0aGUgYXJlYQogKiAqIHBvaW50ZWQgdG8gYnkgcGFja2V0LiAgb3V0X2xlbmd0aCBpcyB0aGUgc2l6ZSBvZiB0aGUgZGF0YSBhcmVhIGF2YWlsYWJsZS4KICogKiBSZXR1cm5zIHRoZSBsZW5ndGggb2YgdGhlIGNvbXBsZXRlZCBwYWNrZXQgaW4gb3V0X2xlbmd0aC4gIElmIGFueSBlcnJvcnMKICogKiBvY2N1ciwgLTEgaXMgcmV0dXJuZWQuICBJZiBhbGwgZ29lcyB3ZWxsLCAwIGlzIHJldHVybmVkLgogKi8Kc3RhdGljIGludApzbm1wdjNfYnVpbGQodV9jaGFyICoqIHBrdCwgc2l6ZV90ICogcGt0X2xlbiwgc2l6ZV90ICogb2Zmc2V0LAogICAgICAgICAgICAgbmV0c25tcF9zZXNzaW9uICogc2Vzc2lvbiwgbmV0c25tcF9wZHUgKnBkdSkKewogICAgaW50ICAgICAgICAgICAgIHJldDsKCiAgICBzZXNzaW9uLT5zX3NubXBfZXJybm8gPSAwOwogICAgc2Vzc2lvbi0+c19lcnJubyA9IDA7CgogICAgLyoKICAgICAqIGRvIHZhbGlkYXRpb24gZm9yIFBEVSB0eXBlcyAKICAgICAqLwogICAgc3dpdGNoIChwZHUtPmNvbW1hbmQpIHsKICAgIGNhc2UgU05NUF9NU0dfUkVTUE9OU0U6CiAgICBjYXNlIFNOTVBfTVNHX1RSQVAyOgogICAgY2FzZSBTTk1QX01TR19SRVBPUlQ6CiAgICAgICAgbmV0c25tcF9hc3NlcnQoMCA9PSAocGR1LT5mbGFncyAmIFVDRF9NU0dfRkxBR19FWFBFQ1RfUkVTUE9OU0UpKTsKICAgICAgICAvKgogICAgICAgICAqIEZhbGx0aHJvdWdoIAogICAgICAgICAqLwogICAgY2FzZSBTTk1QX01TR19HRVQ6CiAgICBjYXNlIFNOTVBfTVNHX0dFVE5FWFQ6CiAgICBjYXNlIFNOTVBfTVNHX1NFVDoKICAgIGNhc2UgU05NUF9NU0dfSU5GT1JNOgogICAgICAgIGlmIChwZHUtPmVycnN0YXQgPT0gU05NUF9ERUZBVUxUX0VSUlNUQVQpCiAgICAgICAgICAgIHBkdS0+ZXJyc3RhdCA9IDA7CiAgICAgICAgaWYgKHBkdS0+ZXJyaW5kZXggPT0gU05NUF9ERUZBVUxUX0VSUklOREVYKQogICAgICAgICAgICBwZHUtPmVycmluZGV4ID0gMDsKICAgICAgICBicmVhazsKCiAgICBjYXNlIFNOTVBfTVNHX0dFVEJVTEs6CiAgICAgICAgaWYgKHBkdS0+bWF4X3JlcGV0aXRpb25zIDwgMCkgewogICAgICAgICAgICBzZXNzaW9uLT5zX3NubXBfZXJybm8gPSBTTk1QRVJSX0JBRF9SRVBFVElUSU9OUzsKICAgICAgICAgICAgcmV0dXJuIC0xOwogICAgICAgIH0KICAgICAgICBpZiAocGR1LT5ub25fcmVwZWF0ZXJzIDwgMCkgewogICAgICAgICAgICBzZXNzaW9uLT5zX3NubXBfZXJybm8gPSBTTk1QRVJSX0JBRF9SRVBFQVRFUlM7CiAgICAgICAgICAgIHJldHVybiAtMTsKICAgICAgICB9CiAgICAgICAgYnJlYWs7CgogICAgY2FzZSBTTk1QX01TR19UUkFQOgogICAgICAgIHNlc3Npb24tPnNfc25tcF9lcnJubyA9IFNOTVBFUlJfVjFfSU5fVjI7CiAgICAgICAgcmV0dXJuIC0xOwoKICAgIGRlZmF1bHQ6CiAgICAgICAgc2Vzc2lvbi0+c19zbm1wX2Vycm5vID0gU05NUEVSUl9VTktOT1dOX1BEVTsKICAgICAgICByZXR1cm4gLTE7CiAgICB9CgogICAgLyogRG8gd2UgbmVlZCB0byBzZXQgdGhlIHNlc3Npb24gc2VjdXJpdHkgZW5naW5laWQ/ICovCiAgICBpZiAocGR1LT5zZWN1cml0eUVuZ2luZUlETGVuID09IDApIHsKICAgICAgICBpZiAoc2Vzc2lvbi0+c2VjdXJpdHlFbmdpbmVJRExlbikgewogICAgICAgICAgICBzbm1wdjNfY2xvbmVfZW5naW5lSUQoJnBkdS0+c2VjdXJpdHlFbmdpbmVJRCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZwZHUtPnNlY3VyaXR5RW5naW5lSURMZW4sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZXNzaW9uLT5zZWN1cml0eUVuZ2luZUlELAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2Vzc2lvbi0+c2VjdXJpdHlFbmdpbmVJRExlbik7CiAgICAgICAgfQogICAgfQogICAgCiAgICAvKiBEbyB3ZSBuZWVkIHRvIHNldCB0aGUgc2Vzc2lvbiBjb250ZXh0IGVuZ2luZWlkPyAqLwogICAgaWYgKHBkdS0+Y29udGV4dEVuZ2luZUlETGVuID09IDApIHsKICAgICAgICBpZiAoc2Vzc2lvbi0+Y29udGV4dEVuZ2luZUlETGVuKSB7CiAgICAgICAgICAgIHNubXB2M19jbG9uZV9lbmdpbmVJRCgmcGR1LT5jb250ZXh0RW5naW5lSUQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmcGR1LT5jb250ZXh0RW5naW5lSURMZW4sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZXNzaW9uLT5jb250ZXh0RW5naW5lSUQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZXNzaW9uLT5jb250ZXh0RW5naW5lSURMZW4pOwogICAgICAgIH0gZWxzZSBpZiAocGR1LT5zZWN1cml0eUVuZ2luZUlETGVuKSB7CiAgICAgICAgICAgIHNubXB2M19jbG9uZV9lbmdpbmVJRCgmcGR1LT5jb250ZXh0RW5naW5lSUQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmcGR1LT5jb250ZXh0RW5naW5lSURMZW4sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwZHUtPnNlY3VyaXR5RW5naW5lSUQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwZHUtPnNlY3VyaXR5RW5naW5lSURMZW4pOwogICAgICAgIH0KICAgIH0KCiAgICBpZiAocGR1LT5jb250ZXh0TmFtZSA9PSBOVUxMKSB7CiAgICAgICAgaWYgKCFzZXNzaW9uLT5jb250ZXh0TmFtZSkgewogICAgICAgICAgICBzZXNzaW9uLT5zX3NubXBfZXJybm8gPSBTTk1QRVJSX0JBRF9DT05URVhUOwogICAgICAgICAgICByZXR1cm4gLTE7CiAgICAgICAgfQogICAgICAgIHBkdS0+Y29udGV4dE5hbWUgPSBzdHJkdXAoc2Vzc2lvbi0+Y29udGV4dE5hbWUpOwogICAgICAgIGlmIChwZHUtPmNvbnRleHROYW1lID09IE5VTEwpIHsKICAgICAgICAgICAgc2Vzc2lvbi0+c19zbm1wX2Vycm5vID0gU05NUEVSUl9HRU5FUlI7CiAgICAgICAgICAgIHJldHVybiAtMTsKICAgICAgICB9CiAgICAgICAgcGR1LT5jb250ZXh0TmFtZUxlbiA9IHNlc3Npb24tPmNvbnRleHROYW1lTGVuOwogICAgfQogICAgaWYgKHBkdS0+c2VjdXJpdHlNb2RlbCA9PSBTTk1QX0RFRkFVTFRfU0VDTU9ERUwpIHsKICAgICAgICBwZHUtPnNlY3VyaXR5TW9kZWwgPSBzZXNzaW9uLT5zZWN1cml0eU1vZGVsOwogICAgICAgIGlmIChwZHUtPnNlY3VyaXR5TW9kZWwgPT0gU05NUF9ERUZBVUxUX1NFQ01PREVMKSB7CiAgICAgICAgICAgIHBkdS0+c2VjdXJpdHlNb2RlbCA9IFNOTVBfU0VDX01PREVMX1VTTTsKICAgICAgICB9CiAgICB9CiAgICBpZiAocGR1LT5zZWN1cml0eU5hbWVMZW4gPT0gMCAmJiBwZHUtPnNlY3VyaXR5TmFtZSA9PSAwKSB7CiAgICAgICAgaWYgKHNlc3Npb24tPnNlY3VyaXR5TmFtZUxlbiA9PSAwKSB7CiAgICAgICAgICAgIHNlc3Npb24tPnNfc25tcF9lcnJubyA9IFNOTVBFUlJfQkFEX1NFQ19OQU1FOwogICAgICAgICAgICByZXR1cm4gLTE7CiAgICAgICAgfQogICAgICAgIHBkdS0+c2VjdXJpdHlOYW1lID0gc3RyZHVwKHNlc3Npb24tPnNlY3VyaXR5TmFtZSk7CiAgICAgICAgaWYgKHBkdS0+c2VjdXJpdHlOYW1lID09IE5VTEwpIHsKICAgICAgICAgICAgc2Vzc2lvbi0+c19zbm1wX2Vycm5vID0gU05NUEVSUl9HRU5FUlI7CiAgICAgICAgICAgIHJldHVybiAtMTsKICAgICAgICB9CiAgICAgICAgcGR1LT5zZWN1cml0eU5hbWVMZW4gPSBzZXNzaW9uLT5zZWN1cml0eU5hbWVMZW47CiAgICB9CiAgICBpZiAocGR1LT5zZWN1cml0eUxldmVsID09IDApIHsKICAgICAgICBpZiAoc2Vzc2lvbi0+c2VjdXJpdHlMZXZlbCA9PSAwKSB7CiAgICAgICAgICAgIHNlc3Npb24tPnNfc25tcF9lcnJubyA9IFNOTVBFUlJfQkFEX1NFQ19MRVZFTDsKICAgICAgICAgICAgcmV0dXJuIC0xOwogICAgICAgIH0KICAgICAgICBwZHUtPnNlY3VyaXR5TGV2ZWwgPSBzZXNzaW9uLT5zZWN1cml0eUxldmVsOwogICAgfQogICAgREVCVUdNU0dUTCgoInNubXBfYnVpbGQiLAogICAgICAgICAgICAgICAgIkJ1aWxkaW5nIFNOTVB2MyBtZXNzYWdlIChzZWNOYW1lOlwiJXNcIiwgc2VjTGV2ZWw6JXMpLi4uXG4iLAogICAgICAgICAgICAgICAgKChzZXNzaW9uLT5zZWN1cml0eU5hbWUpID8gKGNoYXIgKikgc2Vzc2lvbi0+c2VjdXJpdHlOYW1lIDoKICAgICAgICAgICAgICAgICAoKHBkdS0+c2VjdXJpdHlOYW1lKSA/IChjaGFyICopIHBkdS0+c2VjdXJpdHlOYW1lIDoKICAgICAgICAgICAgICAgICAgIkVSUk9SOiB1bmRlZmluZWQiKSksIHNlY0xldmVsTmFtZVtwZHUtPnNlY3VyaXR5TGV2ZWxdKSk7CgogICAgREVCVUdEVU1QU0VDVElPTigic2VuZCIsICJTTk1QdjMgTWVzc2FnZSIpOwojaWZkZWYgTkVUU05NUF9VU0VfUkVWRVJTRV9BU05FTkNPRElORwogICAgaWYgKG5ldHNubXBfZHNfZ2V0X2Jvb2xlYW4oTkVUU05NUF9EU19MSUJSQVJZX0lELCBORVRTTk1QX0RTX0xJQl9SRVZFUlNFX0VOQ09ERSkpIHsKICAgICAgICByZXQgPSBzbm1wdjNfcGFja2V0X3JlYWxsb2NfcmJ1aWxkKHBrdCwgcGt0X2xlbiwgb2Zmc2V0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2Vzc2lvbiwgcGR1LCBOVUxMLCAwKTsKICAgIH0gZWxzZSB7CiNlbmRpZgogICAgICAgIHJldCA9IHNubXB2M19wYWNrZXRfYnVpbGQoc2Vzc2lvbiwgcGR1LCAqcGt0LCBwa3RfbGVuLCBOVUxMLCAwKTsKI2lmZGVmIE5FVFNOTVBfVVNFX1JFVkVSU0VfQVNORU5DT0RJTkcKICAgIH0KI2VuZGlmCiAgICBERUJVR0lOREVOVExFU1MoKTsKICAgIGlmICgtMSAhPSByZXQpIHsKICAgICAgICBzZXNzaW9uLT5zX3NubXBfZXJybm8gPSByZXQ7CiAgICB9CgogICAgcmV0dXJuIHJldDsKCn0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogZW5kIHNubXB2M19idWlsZCgpICovCgoKCgpzdGF0aWMgdV9jaGFyICAqCnNubXB2M19oZWFkZXJfYnVpbGQobmV0c25tcF9zZXNzaW9uICogc2Vzc2lvbiwgbmV0c25tcF9wZHUgKnBkdSwKICAgICAgICAgICAgICAgICAgICB1X2NoYXIgKiBwYWNrZXQsIHNpemVfdCAqIG91dF9sZW5ndGgsCiAgICAgICAgICAgICAgICAgICAgc2l6ZV90IGxlbmd0aCwgdV9jaGFyICoqIG1zZ19oZHJfZSkKewogICAgdV9jaGFyICAgICAgICAgKmdsb2JhbF9oZHIsICpnbG9iYWxfaGRyX2U7CiAgICB1X2NoYXIgICAgICAgICAqY3A7CiAgICB1X2NoYXIgICAgICAgICAgbXNnX2ZsYWdzOwogICAgbG9uZyAgICAgICAgICAgIG1heF9zaXplOwogICAgbG9uZyAgICAgICAgICAgIHNlY19tb2RlbDsKICAgIHVfY2hhciAgICAgICAgICpwYiwgKnBiMGU7CgogICAgLyoKICAgICAqIFNhdmUgY3VycmVudCBsb2NhdGlvbiBhbmQgYnVpbGQgU0VRVUVOQ0UgdGFnIGFuZCBsZW5ndGggcGxhY2Vob2xkZXIKICAgICAqICogZm9yIFNOTVAgbWVzc2FnZSBzZXF1ZW5jZSAoYWN0dWFsIGxlbmd0aCBpbnNlcnRlZCBsYXRlcikKICAgICAqLwogICAgY3AgPSBhc25fYnVpbGRfc2VxdWVuY2UocGFja2V0LCBvdXRfbGVuZ3RoLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgKHVfY2hhcikgKEFTTl9TRVFVRU5DRSB8IEFTTl9DT05TVFJVQ1RPUiksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBsZW5ndGgpOwogICAgaWYgKGNwID09IE5VTEwpCiAgICAgICAgcmV0dXJuIE5VTEw7CiAgICBpZiAobXNnX2hkcl9lICE9IE5VTEwpCiAgICAgICAgKm1zZ19oZHJfZSA9IGNwOwogICAgcGIwZSA9IGNwOwoKCiAgICAvKgogICAgICogc3RvcmUgdGhlIHZlcnNpb24gZmllbGQgLSBtc2dWZXJzaW9uCiAgICAgKi8KICAgIERFQlVHRFVNUEhFQURFUigic2VuZCIsICJTTk1QIFZlcnNpb24gTnVtYmVyIik7CiAgICBjcCA9IGFzbl9idWlsZF9pbnQoY3AsIG91dF9sZW5ndGgsCiAgICAgICAgICAgICAgICAgICAgICAgKHVfY2hhcikgKEFTTl9VTklWRVJTQUwgfCBBU05fUFJJTUlUSVZFIHwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQVNOX0lOVEVHRVIpLCAobG9uZyAqKSAmcGR1LT52ZXJzaW9uLAogICAgICAgICAgICAgICAgICAgICAgIHNpemVvZihwZHUtPnZlcnNpb24pKTsKICAgIERFQlVHSU5ERU5UTEVTUygpOwogICAgaWYgKGNwID09IE5VTEwpCiAgICAgICAgcmV0dXJuIE5VTEw7CgogICAgZ2xvYmFsX2hkciA9IGNwOwogICAgLyoKICAgICAqIG1zZ0dsb2JhbERhdGEgSGVhZGVyRGF0YSAKICAgICAqLwogICAgREVCVUdEVU1QU0VDVElPTigic2VuZCIsICJtc2dHbG9iYWxEYXRhIik7CiAgICBjcCA9IGFzbl9idWlsZF9zZXF1ZW5jZShjcCwgb3V0X2xlbmd0aCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICh1X2NoYXIpIChBU05fU0VRVUVOQ0UgfCBBU05fQ09OU1RSVUNUT1IpLCAwKTsKICAgIGlmIChjcCA9PSBOVUxMKQogICAgICAgIHJldHVybiBOVUxMOwogICAgZ2xvYmFsX2hkcl9lID0gY3A7CgoKICAgIC8qCiAgICAgKiBtc2dJRCAKICAgICAqLwogICAgREVCVUdEVU1QSEVBREVSKCJzZW5kIiwgIm1zZ0lEIik7CiAgICBjcCA9IGFzbl9idWlsZF9pbnQoY3AsIG91dF9sZW5ndGgsCiAgICAgICAgICAgICAgICAgICAgICAgKHVfY2hhcikgKEFTTl9VTklWRVJTQUwgfCBBU05fUFJJTUlUSVZFIHwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQVNOX0lOVEVHRVIpLCAmcGR1LT5tc2dpZCwKICAgICAgICAgICAgICAgICAgICAgICBzaXplb2YocGR1LT5tc2dpZCkpOwogICAgREVCVUdJTkRFTlRMRVNTKCk7CiAgICBpZiAoY3AgPT0gTlVMTCkKICAgICAgICByZXR1cm4gTlVMTDsKCiAgICAvKgogICAgICogbXNnTWF4U2l6ZSAKICAgICAqLwogICAgbWF4X3NpemUgPSBzZXNzaW9uLT5yY3ZNc2dNYXhTaXplOwogICAgREVCVUdEVU1QSEVBREVSKCJzZW5kIiwgIm1zZ01heFNpemUiKTsKICAgIGNwID0gYXNuX2J1aWxkX2ludChjcCwgb3V0X2xlbmd0aCwKICAgICAgICAgICAgICAgICAgICAgICAodV9jaGFyKSAoQVNOX1VOSVZFUlNBTCB8IEFTTl9QUklNSVRJVkUgfAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBU05fSU5URUdFUiksICZtYXhfc2l6ZSwKICAgICAgICAgICAgICAgICAgICAgICBzaXplb2YobWF4X3NpemUpKTsKICAgIERFQlVHSU5ERU5UTEVTUygpOwogICAgaWYgKGNwID09IE5VTEwpCiAgICAgICAgcmV0dXJuIE5VTEw7CgogICAgLyoKICAgICAqIG1zZ0ZsYWdzIAogICAgICovCiAgICBzbm1wdjNfY2FsY19tc2dfZmxhZ3MocGR1LT5zZWN1cml0eUxldmVsLCBwZHUtPmNvbW1hbmQsICZtc2dfZmxhZ3MpOwogICAgREVCVUdEVU1QSEVBREVSKCJzZW5kIiwgIm1zZ0ZsYWdzIik7CiAgICBjcCA9IGFzbl9idWlsZF9zdHJpbmcoY3AsIG91dF9sZW5ndGgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgKHVfY2hhcikgKEFTTl9VTklWRVJTQUwgfCBBU05fUFJJTUlUSVZFIHwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQVNOX09DVEVUX1NUUiksICZtc2dfZmxhZ3MsCiAgICAgICAgICAgICAgICAgICAgICAgICAgc2l6ZW9mKG1zZ19mbGFncykpOwogICAgREVCVUdJTkRFTlRMRVNTKCk7CiAgICBpZiAoY3AgPT0gTlVMTCkKICAgICAgICByZXR1cm4gTlVMTDsKCiAgICAvKgogICAgICogbXNnU2VjdXJpdHlNb2RlbCAKICAgICAqLwogICAgc2VjX21vZGVsID0gcGR1LT5zZWN1cml0eU1vZGVsOwogICAgREVCVUdEVU1QSEVBREVSKCJzZW5kIiwgIm1zZ1NlY3VyaXR5TW9kZWwiKTsKICAgIGNwID0gYXNuX2J1aWxkX2ludChjcCwgb3V0X2xlbmd0aCwKICAgICAgICAgICAgICAgICAgICAgICAodV9jaGFyKSAoQVNOX1VOSVZFUlNBTCB8IEFTTl9QUklNSVRJVkUgfAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBU05fSU5URUdFUiksICZzZWNfbW9kZWwsCiAgICAgICAgICAgICAgICAgICAgICAgc2l6ZW9mKHNlY19tb2RlbCkpOwogICAgREVCVUdJTkRFTlRBREQoLTQpOyAgICAgICAgIC8qIHJldHVybiBmcm9tIGdsb2JhbCBkYXRhIGluZGVudCAqLwogICAgaWYgKGNwID09IE5VTEwpCiAgICAgICAgcmV0dXJuIE5VTEw7CgoKICAgIC8qCiAgICAgKiBpbnNlcnQgYWN0dWFsIGxlbmd0aCBvZiBnbG9iYWxEYXRhCiAgICAgKi8KICAgIHBiID0gYXNuX2J1aWxkX3NlcXVlbmNlKGdsb2JhbF9oZHIsIG91dF9sZW5ndGgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAodV9jaGFyKSAoQVNOX1NFUVVFTkNFIHwgQVNOX0NPTlNUUlVDVE9SKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNwIC0gZ2xvYmFsX2hkcl9lKTsKICAgIGlmIChwYiA9PSBOVUxMKQogICAgICAgIHJldHVybiBOVUxMOwoKCiAgICAvKgogICAgICogaW5zZXJ0IHRoZSBhY3R1YWwgbGVuZ3RoIG9mIHRoZSBlbnRpcmUgcGFja2V0CiAgICAgKi8KICAgIHBiID0gYXNuX2J1aWxkX3NlcXVlbmNlKHBhY2tldCwgb3V0X2xlbmd0aCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICh1X2NoYXIpIChBU05fU0VRVUVOQ0UgfCBBU05fQ09OU1RSVUNUT1IpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgbGVuZ3RoICsgKGNwIC0gcGIwZSkpOwogICAgaWYgKHBiID09IE5VTEwpCiAgICAgICAgcmV0dXJuIE5VTEw7CgogICAgcmV0dXJuIGNwOwoKfSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiBlbmQgc25tcHYzX2hlYWRlcl9idWlsZCgpICovCgojaWZkZWYgTkVUU05NUF9VU0VfUkVWRVJTRV9BU05FTkNPRElORwoKaW50CnNubXB2M19oZWFkZXJfcmVhbGxvY19yYnVpbGQodV9jaGFyICoqIHBrdCwgc2l6ZV90ICogcGt0X2xlbiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaXplX3QgKiBvZmZzZXQsIG5ldHNubXBfc2Vzc2lvbiAqIHNlc3Npb24sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV0c25tcF9wZHUgKnBkdSkKewogICAgc2l6ZV90ICAgICAgICAgIHN0YXJ0X29mZnNldCA9ICpvZmZzZXQ7CiAgICB1X2NoYXIgICAgICAgICAgbXNnX2ZsYWdzOwogICAgbG9uZyAgICAgICAgICAgIG1heF9zaXplLCBzZWNfbW9kZWw7CiAgICBpbnQgICAgICAgICAgICAgcmMgPSAwOwoKICAgIC8qCiAgICAgKiBtc2dTZWN1cml0eU1vZGVsLiAgCiAgICAgKi8KICAgIHNlY19tb2RlbCA9IHBkdS0+c2VjdXJpdHlNb2RlbDsKICAgIERFQlVHRFVNUEhFQURFUigic2VuZCIsICJtc2dTZWN1cml0eU1vZGVsIik7CiAgICByYyA9IGFzbl9yZWFsbG9jX3JidWlsZF9pbnQocGt0LCBwa3RfbGVuLCBvZmZzZXQsIDEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKHVfY2hhcikgKEFTTl9VTklWRVJTQUwgfCBBU05fUFJJTUlUSVZFIHwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQVNOX0lOVEVHRVIpLCAmc2VjX21vZGVsLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNpemVvZihzZWNfbW9kZWwpKTsKICAgIERFQlVHSU5ERU5UTEVTUygpOwogICAgaWYgKHJjID09IDApIHsKICAgICAgICByZXR1cm4gMDsKICAgIH0KCiAgICAvKgogICAgICogbXNnRmxhZ3MuICAKICAgICAqLwogICAgc25tcHYzX2NhbGNfbXNnX2ZsYWdzKHBkdS0+c2VjdXJpdHlMZXZlbCwgcGR1LT5jb21tYW5kLCAmbXNnX2ZsYWdzKTsKICAgIERFQlVHRFVNUEhFQURFUigic2VuZCIsICJtc2dGbGFncyIpOwogICAgcmMgPSBhc25fcmVhbGxvY19yYnVpbGRfc3RyaW5nKHBrdCwgcGt0X2xlbiwgb2Zmc2V0LCAxLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICh1X2NoYXIpIChBU05fVU5JVkVSU0FMIHwgQVNOX1BSSU1JVElWRQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8IEFTTl9PQ1RFVF9TVFIpLCAmbXNnX2ZsYWdzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNpemVvZihtc2dfZmxhZ3MpKTsKICAgIERFQlVHSU5ERU5UTEVTUygpOwogICAgaWYgKHJjID09IDApIHsKICAgICAgICByZXR1cm4gMDsKICAgIH0KCiAgICAvKgogICAgICogbXNnTWF4U2l6ZS4gIAogICAgICovCiAgICBtYXhfc2l6ZSA9IHNlc3Npb24tPnJjdk1zZ01heFNpemU7CiAgICBERUJVR0RVTVBIRUFERVIoInNlbmQiLCAibXNnTWF4U2l6ZSIpOwogICAgcmMgPSBhc25fcmVhbGxvY19yYnVpbGRfaW50KHBrdCwgcGt0X2xlbiwgb2Zmc2V0LCAxLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICh1X2NoYXIpIChBU05fVU5JVkVSU0FMIHwgQVNOX1BSSU1JVElWRSB8CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEFTTl9JTlRFR0VSKSwgJm1heF9zaXplLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNpemVvZihtYXhfc2l6ZSkpOwogICAgREVCVUdJTkRFTlRMRVNTKCk7CiAgICBpZiAocmMgPT0gMCkgewogICAgICAgIHJldHVybiAwOwogICAgfQoKICAgIC8qCiAgICAgKiBtc2dJRC4gIAogICAgICovCiAgICBERUJVR0RVTVBIRUFERVIoInNlbmQiLCAibXNnSUQiKTsKICAgIHJjID0gYXNuX3JlYWxsb2NfcmJ1aWxkX2ludChwa3QsIHBrdF9sZW4sIG9mZnNldCwgMSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAodV9jaGFyKSAoQVNOX1VOSVZFUlNBTCB8IEFTTl9QUklNSVRJVkUgfAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBU05fSU5URUdFUiksICZwZHUtPm1zZ2lkLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNpemVvZihwZHUtPm1zZ2lkKSk7CiAgICBERUJVR0lOREVOVExFU1MoKTsKICAgIGlmIChyYyA9PSAwKSB7CiAgICAgICAgcmV0dXJuIDA7CiAgICB9CgogICAgLyoKICAgICAqIEdsb2JhbCBkYXRhIHNlcXVlbmNlLiAgCiAgICAgKi8KICAgIHJjID0gYXNuX3JlYWxsb2NfcmJ1aWxkX3NlcXVlbmNlKHBrdCwgcGt0X2xlbiwgb2Zmc2V0LCAxLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKHVfY2hhcikgKEFTTl9TRVFVRU5DRSB8CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQVNOX0NPTlNUUlVDVE9SKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICpvZmZzZXQgLSBzdGFydF9vZmZzZXQpOwogICAgaWYgKHJjID09IDApIHsKICAgICAgICByZXR1cm4gMDsKICAgIH0KCiAgICAvKgogICAgICogU3RvcmUgdGhlIHZlcnNpb24gZmllbGQgLSBtc2dWZXJzaW9uLiAgCiAgICAgKi8KICAgIERFQlVHRFVNUEhFQURFUigic2VuZCIsICJTTk1QIFZlcnNpb24gTnVtYmVyIik7CiAgICByYyA9IGFzbl9yZWFsbG9jX3JidWlsZF9pbnQocGt0LCBwa3RfbGVuLCBvZmZzZXQsIDEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKHVfY2hhcikgKEFTTl9VTklWRVJTQUwgfCBBU05fUFJJTUlUSVZFIHwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQVNOX0lOVEVHRVIpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChsb25nICopICZwZHUtPnZlcnNpb24sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2l6ZW9mKHBkdS0+dmVyc2lvbikpOwogICAgREVCVUdJTkRFTlRMRVNTKCk7CiAgICByZXR1cm4gcmM7Cn0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogZW5kIHNubXB2M19oZWFkZXJfcmVhbGxvY19yYnVpbGQoKSAqLwojZW5kaWYgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIE5FVFNOTVBfVVNFX1JFVkVSU0VfQVNORU5DT0RJTkcgKi8KCnN0YXRpYyB1X2NoYXIgICoKc25tcHYzX3Njb3BlZFBEVV9oZWFkZXJfYnVpbGQobmV0c25tcF9wZHUgKnBkdSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdV9jaGFyICogcGFja2V0LCBzaXplX3QgKiBvdXRfbGVuZ3RoLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1X2NoYXIgKiogc3BkdV9lKQp7CiAgICB1X2NoYXIgICAgICAgICAqc2NvcGVkUGR1LCAqcGI7CgogICAgcGIgPSBzY29wZWRQZHUgPSBwYWNrZXQ7CiAgICBwYiA9IGFzbl9idWlsZF9zZXF1ZW5jZShwYiwgb3V0X2xlbmd0aCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICh1X2NoYXIpIChBU05fU0VRVUVOQ0UgfCBBU05fQ09OU1RSVUNUT1IpLCAwKTsKICAgIGlmIChwYiA9PSBOVUxMKQogICAgICAgIHJldHVybiBOVUxMOwogICAgaWYgKHNwZHVfZSkKICAgICAgICAqc3BkdV9lID0gcGI7CgogICAgREVCVUdEVU1QSEVBREVSKCJzZW5kIiwgImNvbnRleHRFbmdpbmVJRCIpOwogICAgcGIgPSBhc25fYnVpbGRfc3RyaW5nKHBiLCBvdXRfbGVuZ3RoLAogICAgICAgICAgICAgICAgICAgICAgICAgIChBU05fVU5JVkVSU0FMIHwgQVNOX1BSSU1JVElWRSB8IEFTTl9PQ1RFVF9TVFIpLAogICAgICAgICAgICAgICAgICAgICAgICAgIHBkdS0+Y29udGV4dEVuZ2luZUlELCBwZHUtPmNvbnRleHRFbmdpbmVJRExlbik7CiAgICBERUJVR0lOREVOVExFU1MoKTsKICAgIGlmIChwYiA9PSBOVUxMKQogICAgICAgIHJldHVybiBOVUxMOwoKICAgIERFQlVHRFVNUEhFQURFUigic2VuZCIsICJjb250ZXh0TmFtZSIpOwogICAgcGIgPSBhc25fYnVpbGRfc3RyaW5nKHBiLCBvdXRfbGVuZ3RoLAogICAgICAgICAgICAgICAgICAgICAgICAgIChBU05fVU5JVkVSU0FMIHwgQVNOX1BSSU1JVElWRSB8IEFTTl9PQ1RFVF9TVFIpLAogICAgICAgICAgICAgICAgICAgICAgICAgICh1X2NoYXIgKikgcGR1LT5jb250ZXh0TmFtZSwKICAgICAgICAgICAgICAgICAgICAgICAgICBwZHUtPmNvbnRleHROYW1lTGVuKTsKICAgIERFQlVHSU5ERU5UTEVTUygpOwogICAgaWYgKHBiID09IE5VTEwpCiAgICAgICAgcmV0dXJuIE5VTEw7CgogICAgcmV0dXJuIHBiOwoKfSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiBlbmQgc25tcHYzX3Njb3BlZFBEVV9oZWFkZXJfYnVpbGQoKSAqLwoKCiNpZmRlZiBORVRTTk1QX1VTRV9SRVZFUlNFX0FTTkVOQ09ESU5HCmludApzbm1wdjNfc2NvcGVkUERVX2hlYWRlcl9yZWFsbG9jX3JidWlsZCh1X2NoYXIgKiogcGt0LCBzaXplX3QgKiBwa3RfbGVuLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaXplX3QgKiBvZmZzZXQsIG5ldHNubXBfcGR1ICpwZHUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNpemVfdCBib2R5X2xlbikKewogICAgc2l6ZV90ICAgICAgICAgIHN0YXJ0X29mZnNldCA9ICpvZmZzZXQ7CiAgICBpbnQgICAgICAgICAgICAgcmMgPSAwOwoKICAgIC8qCiAgICAgKiBjb250ZXh0TmFtZS4gIAogICAgICovCiAgICBERUJVR0RVTVBIRUFERVIoInNlbmQiLCAiY29udGV4dE5hbWUiKTsKICAgIHJjID0gYXNuX3JlYWxsb2NfcmJ1aWxkX3N0cmluZyhwa3QsIHBrdF9sZW4sIG9mZnNldCwgMSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAodV9jaGFyKSAoQVNOX1VOSVZFUlNBTCB8IEFTTl9QUklNSVRJVkUKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfCBBU05fT0NURVRfU1RSKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAodV9jaGFyICopIHBkdS0+Y29udGV4dE5hbWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGR1LT5jb250ZXh0TmFtZUxlbik7CiAgICBERUJVR0lOREVOVExFU1MoKTsKICAgIGlmIChyYyA9PSAwKSB7CiAgICAgICAgcmV0dXJuIDA7CiAgICB9CgogICAgLyoKICAgICAqIGNvbnRleHRFbmdpbmVJRC4gIAogICAgICovCiAgICBERUJVR0RVTVBIRUFERVIoInNlbmQiLCAiY29udGV4dEVuZ2luZUlEIik7CiAgICByYyA9IGFzbl9yZWFsbG9jX3JidWlsZF9zdHJpbmcocGt0LCBwa3RfbGVuLCBvZmZzZXQsIDEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKHVfY2hhcikgKEFTTl9VTklWRVJTQUwgfCBBU05fUFJJTUlUSVZFCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgQVNOX09DVEVUX1NUUiksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGR1LT5jb250ZXh0RW5naW5lSUQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGR1LT5jb250ZXh0RW5naW5lSURMZW4pOwogICAgREVCVUdJTkRFTlRMRVNTKCk7CiAgICBpZiAocmMgPT0gMCkgewogICAgICAgIHJldHVybiAwOwogICAgfQoKICAgIHJjID0gYXNuX3JlYWxsb2NfcmJ1aWxkX3NlcXVlbmNlKHBrdCwgcGt0X2xlbiwgb2Zmc2V0LCAxLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKHVfY2hhcikgKEFTTl9TRVFVRU5DRSB8CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQVNOX0NPTlNUUlVDVE9SKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICpvZmZzZXQgLSBzdGFydF9vZmZzZXQgKyBib2R5X2xlbik7CgogICAgcmV0dXJuIHJjOwp9ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIGVuZCBzbm1wdjNfc2NvcGVkUERVX2hlYWRlcl9yZWFsbG9jX3JidWlsZCgpICovCiNlbmRpZiAgICAgICAgICAgICAgICAgICAgICAgICAgLyogTkVUU05NUF9VU0VfUkVWRVJTRV9BU05FTkNPRElORyAqLwoKI2lmZGVmIE5FVFNOTVBfVVNFX1JFVkVSU0VfQVNORU5DT0RJTkcKLyoKICogcmV0dXJucyAwIGlmIHN1Y2Nlc3MsIC0xIGlmIGZhaWwsIG5vdCAwIGlmIFNNIGJ1aWxkIGZhaWx1cmUgCiAqLwppbnQKc25tcHYzX3BhY2tldF9yZWFsbG9jX3JidWlsZCh1X2NoYXIgKiogcGt0LCBzaXplX3QgKiBwa3RfbGVuLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNpemVfdCAqIG9mZnNldCwgbmV0c25tcF9zZXNzaW9uICogc2Vzc2lvbiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXRzbm1wX3BkdSAqcGR1LCB1X2NoYXIgKiBwZHVfZGF0YSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaXplX3QgcGR1X2RhdGFfbGVuKQp7CiAgICB1X2NoYXIgICAgICAgICAqc2NvcGVkX3BkdSwgKmhkcmJ1ZiA9IE5VTEwsICpoZHIgPSBOVUxMOwogICAgc2l6ZV90ICAgICAgICAgIGhkcmJ1Zl9sZW4gPSBTTk1QX01BWF9NU0dfVjNfSERSUywgaGRyX29mZnNldCA9CiAgICAgICAgMCwgc3BkdV9vZmZzZXQgPSAwOwogICAgc2l6ZV90ICAgICAgICAgIGJvZHlfZW5kX29mZnNldCA9ICpvZmZzZXQsIGJvZHlfbGVuID0gMDsKICAgIHN0cnVjdCBzbm1wX3NlY21vZF9kZWYgKnNwdHIgPSBOVUxMOwogICAgaW50ICAgICAgICAgICAgIHJjID0gMDsKCiAgICAvKgogICAgICogQnVpbGQgYSBzY29wZWRQRFUgc3RydWN0dXJlIGludG8gdGhlIHBhY2tldCBidWZmZXIuICAKICAgICAqLwogICAgREVCVUdQUklOVFBEVVRZUEUoInNlbmQiLCBwZHUtPmNvbW1hbmQpOwogICAgaWYgKHBkdV9kYXRhKSB7CiAgICAgICAgd2hpbGUgKCgqcGt0X2xlbiAtICpvZmZzZXQpIDwgcGR1X2RhdGFfbGVuKSB7CiAgICAgICAgICAgIGlmICghYXNuX3JlYWxsb2MocGt0LCBwa3RfbGVuKSkgewogICAgICAgICAgICAgICAgcmV0dXJuIC0xOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICAqb2Zmc2V0ICs9IHBkdV9kYXRhX2xlbjsKICAgICAgICBtZW1jcHkoKnBrdCArICpwa3RfbGVuIC0gKm9mZnNldCwgcGR1X2RhdGEsIHBkdV9kYXRhX2xlbik7CiAgICB9IGVsc2UgewogICAgICAgIHJjID0gc25tcF9wZHVfcmVhbGxvY19yYnVpbGQocGt0LCBwa3RfbGVuLCBvZmZzZXQsIHBkdSk7CiAgICAgICAgaWYgKHJjID09IDApIHsKICAgICAgICAgICAgcmV0dXJuIC0xOwogICAgICAgIH0KICAgIH0KICAgIGJvZHlfbGVuID0gKm9mZnNldCAtIGJvZHlfZW5kX29mZnNldDsKCiAgICBERUJVR0RVTVBTRUNUSU9OKCJzZW5kIiwgIlNjb3BlZFBkdSIpOwogICAgcmMgPSBzbm1wdjNfc2NvcGVkUERVX2hlYWRlcl9yZWFsbG9jX3JidWlsZChwa3QsIHBrdF9sZW4sIG9mZnNldCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGR1LCBib2R5X2xlbik7CiAgICBpZiAocmMgPT0gMCkgewogICAgICAgIHJldHVybiAtMTsKICAgIH0KICAgIHNwZHVfb2Zmc2V0ID0gKm9mZnNldDsKICAgIERFQlVHSU5ERU5UQUREKC00KTsgICAgICAgICAvKiAgUmV0dXJuIGZyb20gU2NvcGVkIFBEVS4gICovCgogICAgaWYgKChoZHJidWYgPSAodV9jaGFyICopIG1hbGxvYyhoZHJidWZfbGVuKSkgPT0gTlVMTCkgewogICAgICAgIHJldHVybiAtMTsKICAgIH0KCiAgICByYyA9IHNubXB2M19oZWFkZXJfcmVhbGxvY19yYnVpbGQoJmhkcmJ1ZiwgJmhkcmJ1Zl9sZW4sICZoZHJfb2Zmc2V0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlc3Npb24sIHBkdSk7CiAgICBpZiAocmMgPT0gMCkgewogICAgICAgIFNOTVBfRlJFRShoZHJidWYpOwogICAgICAgIHJldHVybiAtMTsKICAgIH0KICAgIGhkciA9IGhkcmJ1ZiArIGhkcmJ1Zl9sZW4gLSBoZHJfb2Zmc2V0OwogICAgc2NvcGVkX3BkdSA9ICpwa3QgKyAqcGt0X2xlbiAtIHNwZHVfb2Zmc2V0OwoKICAgIC8qCiAgICAgKiBDYWxsIHRoZSBzZWN1cml0eSBtb2R1bGUgdG8gcG9zc2libHkgZW5jcnlwdCBhbmQgYXV0aGVudGljYXRlIHRoZQogICAgICogbWVzc2FnZS0tLXRoZSBlbnRpcmUgbWVzc2FnZSB0byB0cmFuc21pdHRlZCBvbiB0aGUgd2lyZSBpcyByZXR1cm5lZC4gIAogICAgICovCgogICAgc3B0ciA9IGZpbmRfc2VjX21vZChwZHUtPnNlY3VyaXR5TW9kZWwpOwogICAgREVCVUdEVU1QU0VDVElPTigic2VuZCIsICJTTSBtc2dTZWN1cml0eVBhcmFtZXRlcnMiKTsKICAgIGlmIChzcHRyICYmIHNwdHItPmVuY29kZV9yZXZlcnNlKSB7CiAgICAgICAgc3RydWN0IHNubXBfc2VjbW9kX291dGdvaW5nX3BhcmFtcyBwYXJtczsKCiAgICAgICAgcGFybXMubXNnUHJvY01vZGVsID0gcGR1LT5tc2dQYXJzZU1vZGVsOwogICAgICAgIHBhcm1zLmdsb2JhbERhdGEgPSBoZHI7CiAgICAgICAgcGFybXMuZ2xvYmFsRGF0YUxlbiA9IGhkcl9vZmZzZXQ7CiAgICAgICAgcGFybXMubWF4TXNnU2l6ZSA9IFNOTVBfTUFYX01TR19TSVpFOwogICAgICAgIHBhcm1zLnNlY01vZGVsID0gcGR1LT5zZWN1cml0eU1vZGVsOwogICAgICAgIHBhcm1zLnNlY0VuZ2luZUlEID0gcGR1LT5zZWN1cml0eUVuZ2luZUlEOwogICAgICAgIHBhcm1zLnNlY0VuZ2luZUlETGVuID0gcGR1LT5zZWN1cml0eUVuZ2luZUlETGVuOwogICAgICAgIHBhcm1zLnNlY05hbWUgPSBwZHUtPnNlY3VyaXR5TmFtZTsKICAgICAgICBwYXJtcy5zZWNOYW1lTGVuID0gcGR1LT5zZWN1cml0eU5hbWVMZW47CiAgICAgICAgcGFybXMuc2VjTGV2ZWwgPSBwZHUtPnNlY3VyaXR5TGV2ZWw7CiAgICAgICAgcGFybXMuc2NvcGVkUGR1ID0gc2NvcGVkX3BkdTsKICAgICAgICBwYXJtcy5zY29wZWRQZHVMZW4gPSBzcGR1X29mZnNldDsKICAgICAgICBwYXJtcy5zZWNTdGF0ZVJlZiA9IHBkdS0+c2VjdXJpdHlTdGF0ZVJlZjsKICAgICAgICBwYXJtcy53aG9sZU1zZyA9IHBrdDsKICAgICAgICBwYXJtcy53aG9sZU1zZ0xlbiA9IHBrdF9sZW47CiAgICAgICAgcGFybXMud2hvbGVNc2dPZmZzZXQgPSBvZmZzZXQ7CiAgICAgICAgcGFybXMuc2Vzc2lvbiA9IHNlc3Npb247CiAgICAgICAgcGFybXMucGR1ID0gcGR1OwoKICAgICAgICByYyA9ICgqc3B0ci0+ZW5jb2RlX3JldmVyc2UpICgmcGFybXMpOwogICAgfSBlbHNlIHsKICAgICAgICBpZiAoIXNwdHIpIHsKICAgICAgICAgICAgc25tcF9sb2coTE9HX0VSUiwKICAgICAgICAgICAgICAgICAgICAgIm5vIHN1Y2ggc2VjdXJpdHkgc2VydmljZSBhdmFpbGFibGU6ICVkXG4iLAogICAgICAgICAgICAgICAgICAgICBwZHUtPnNlY3VyaXR5TW9kZWwpOwogICAgICAgIH0gZWxzZSBpZiAoIXNwdHItPmVuY29kZV9yZXZlcnNlKSB7CiAgICAgICAgICAgIHNubXBfbG9nKExPR19FUlIsCiAgICAgICAgICAgICAgICAgICAgICJzZWN1cml0eSBzZXJ2aWNlICVkIGRvZXNuJ3Qgc3VwcG9ydCByZXZlcnNlIGVuY29kaW5nLlxuIiwKICAgICAgICAgICAgICAgICAgICAgcGR1LT5zZWN1cml0eU1vZGVsKTsKICAgICAgICB9CiAgICAgICAgcmMgPSAtMTsKICAgIH0KCiAgICBERUJVR0lOREVOVExFU1MoKTsKICAgIFNOTVBfRlJFRShoZHJidWYpOwogICAgcmV0dXJuIHJjOwp9ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIGVuZCBzbm1wdjNfcGFja2V0X3JlYWxsb2NfcmJ1aWxkKCkgKi8KI2VuZGlmICAgICAgICAgICAgICAgICAgICAgICAgICAvKiBORVRTTk1QX1VTRV9SRVZFUlNFX0FTTkVOQ09ESU5HICovCgovKgogKiByZXR1cm5zIDAgaWYgc3VjY2VzcywgLTEgaWYgZmFpbCwgbm90IDAgaWYgU00gYnVpbGQgZmFpbHVyZSAKICovCmludApzbm1wdjNfcGFja2V0X2J1aWxkKG5ldHNubXBfc2Vzc2lvbiAqIHNlc3Npb24sIG5ldHNubXBfcGR1ICpwZHUsCiAgICAgICAgICAgICAgICAgICAgdV9jaGFyICogcGFja2V0LCBzaXplX3QgKiBvdXRfbGVuZ3RoLAogICAgICAgICAgICAgICAgICAgIHVfY2hhciAqIHBkdV9kYXRhLCBzaXplX3QgcGR1X2RhdGFfbGVuKQp7CiAgICB1X2NoYXIgICAgICAgICAqZ2xvYmFsX2RhdGEsICpzZWNfcGFyYW1zLCAqc3BkdV9oZHJfZTsKICAgIHNpemVfdCAgICAgICAgICBnbG9iYWxfZGF0YV9sZW4sIHNlY19wYXJhbXNfbGVuOwogICAgdV9jaGFyICAgICAgICAgIHNwZHVfYnVmW1NOTVBfTUFYX01TR19TSVpFXTsKICAgIHNpemVfdCAgICAgICAgICBzcGR1X2J1Zl9sZW4sIHNwZHVfbGVuOwogICAgdV9jaGFyICAgICAgICAgKmNwOwogICAgaW50ICAgICAgICAgICAgIHJlc3VsdDsKICAgIHN0cnVjdCBzbm1wX3NlY21vZF9kZWYgKnNwdHI7CgogICAgZ2xvYmFsX2RhdGEgPSBwYWNrZXQ7CgogICAgLyoKICAgICAqIGJ1aWxkIHRoZSBoZWFkZXJzIGZvciB0aGUgcGFja2V0LCByZXR1cm5lZCBhZGRyID0gc3RhcnQgb2Ygc2VjUGFyYW1zCiAgICAgKi8KICAgIHNlY19wYXJhbXMgPSBzbm1wdjNfaGVhZGVyX2J1aWxkKHNlc3Npb24sIHBkdSwgZ2xvYmFsX2RhdGEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvdXRfbGVuZ3RoLCAwLCBOVUxMKTsKICAgIGlmIChzZWNfcGFyYW1zID09IE5VTEwpCiAgICAgICAgcmV0dXJuIC0xOwogICAgZ2xvYmFsX2RhdGFfbGVuID0gc2VjX3BhcmFtcyAtIGdsb2JhbF9kYXRhOwogICAgc2VjX3BhcmFtc19sZW4gPSAqb3V0X2xlbmd0aDsgICAgICAgLyogbGVuZ3RoIGxlZnQgaW4gcGFja2V0IGJ1ZiBmb3Igc2VjX3BhcmFtcyAqLwoKCiAgICAvKgogICAgICogYnVpbGQgYSBzY29wZWRQRFUgc3RydWN0dXJlIGludG8gc3BkdV9idWYKICAgICAqLwogICAgc3BkdV9idWZfbGVuID0gU05NUF9NQVhfTVNHX1NJWkU7CiAgICBERUJVR0RVTVBTRUNUSU9OKCJzZW5kIiwgIlNjb3BlZFBkdSIpOwogICAgY3AgPSBzbm1wdjNfc2NvcGVkUERVX2hlYWRlcl9idWlsZChwZHUsIHNwZHVfYnVmLCAmc3BkdV9idWZfbGVuLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmc3BkdV9oZHJfZSk7CiAgICBpZiAoY3AgPT0gTlVMTCkKICAgICAgICByZXR1cm4gLTE7CgogICAgLyoKICAgICAqIGJ1aWxkIHRoZSBQRFUgc3RydWN0dXJlIG9udG8gdGhlIGVuZCBvZiBzcGR1X2J1ZiAKICAgICAqLwogICAgREVCVUdQUklOVFBEVVRZUEUoInNlbmQiLCAoKHBkdV9kYXRhKSA/ICpwZHVfZGF0YSA6IDB4MDApKTsKICAgIGlmIChwZHVfZGF0YSkgewogICAgICAgIG1lbWNweShjcCwgcGR1X2RhdGEsIHBkdV9kYXRhX2xlbik7CiAgICAgICAgY3AgKz0gcGR1X2RhdGFfbGVuOwogICAgfSBlbHNlIHsKICAgICAgICBjcCA9IHNubXBfcGR1X2J1aWxkKHBkdSwgY3AsICZzcGR1X2J1Zl9sZW4pOwogICAgICAgIGlmIChjcCA9PSBOVUxMKQogICAgICAgICAgICByZXR1cm4gLTE7CiAgICB9CiAgICBERUJVR0lOREVOVEFERCgtNCk7ICAgICAgICAgLyogcmV0dXJuIGZyb20gU2NvcGVkIFBEVSAqLwoKICAgIC8qCiAgICAgKiByZS1lbmNvZGUgdGhlIGFjdHVhbCBBU04uMSBsZW5ndGggb2YgdGhlIHNjb3BlZFBkdQogICAgICovCiAgICBzcGR1X2xlbiA9IGNwIC0gc3BkdV9oZHJfZTsgLyogbGVuZ3RoIG9mIHNjb3BlZFBkdSBtaW51cyBBU04uMSBoZWFkZXJzICovCiAgICBzcGR1X2J1Zl9sZW4gPSBTTk1QX01BWF9NU0dfU0laRTsKICAgIGlmIChhc25fYnVpbGRfc2VxdWVuY2Uoc3BkdV9idWYsICZzcGR1X2J1Zl9sZW4sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICh1X2NoYXIpIChBU05fU0VRVUVOQ0UgfCBBU05fQ09OU1RSVUNUT1IpLAogICAgICAgICAgICAgICAgICAgICAgICAgICBzcGR1X2xlbikgPT0gTlVMTCkKICAgICAgICByZXR1cm4gLTE7CiAgICBzcGR1X2xlbiA9IGNwIC0gc3BkdV9idWY7ICAgLyogdGhlIGxlbmd0aCBvZiB0aGUgZW50aXJlIHNjb3BlZFBkdSAqLwoKCiAgICAvKgogICAgICogY2FsbCB0aGUgc2VjdXJpdHkgbW9kdWxlIHRvIHBvc3NpYmx5IGVuY3J5cHQgYW5kIGF1dGhlbnRpY2F0ZSB0aGUKICAgICAqIG1lc3NhZ2UgLSB0aGUgZW50aXJlIG1lc3NhZ2UgdG8gdHJhbnNtaXR0ZWQgb24gdGhlIHdpcmUgaXMgcmV0dXJuZWQKICAgICAqLwogICAgY3AgPSBOVUxMOwogICAgKm91dF9sZW5ndGggPSBTTk1QX01BWF9NU0dfU0laRTsKICAgIERFQlVHRFVNUFNFQ1RJT04oInNlbmQiLCAiU00gbXNnU2VjdXJpdHlQYXJhbWV0ZXJzIik7CiAgICBzcHRyID0gZmluZF9zZWNfbW9kKHBkdS0+c2VjdXJpdHlNb2RlbCk7CiAgICBpZiAoc3B0ciAmJiBzcHRyLT5lbmNvZGVfZm9yd2FyZCkgewogICAgICAgIHN0cnVjdCBzbm1wX3NlY21vZF9vdXRnb2luZ19wYXJhbXMgcGFybXM7CiAgICAgICAgcGFybXMubXNnUHJvY01vZGVsID0gcGR1LT5tc2dQYXJzZU1vZGVsOwogICAgICAgIHBhcm1zLmdsb2JhbERhdGEgPSBnbG9iYWxfZGF0YTsKICAgICAgICBwYXJtcy5nbG9iYWxEYXRhTGVuID0gZ2xvYmFsX2RhdGFfbGVuOwogICAgICAgIHBhcm1zLm1heE1zZ1NpemUgPSBTTk1QX01BWF9NU0dfU0laRTsKICAgICAgICBwYXJtcy5zZWNNb2RlbCA9IHBkdS0+c2VjdXJpdHlNb2RlbDsKICAgICAgICBwYXJtcy5zZWNFbmdpbmVJRCA9IHBkdS0+c2VjdXJpdHlFbmdpbmVJRDsKICAgICAgICBwYXJtcy5zZWNFbmdpbmVJRExlbiA9IHBkdS0+c2VjdXJpdHlFbmdpbmVJRExlbjsKICAgICAgICBwYXJtcy5zZWNOYW1lID0gcGR1LT5zZWN1cml0eU5hbWU7CiAgICAgICAgcGFybXMuc2VjTmFtZUxlbiA9IHBkdS0+c2VjdXJpdHlOYW1lTGVuOwogICAgICAgIHBhcm1zLnNlY0xldmVsID0gcGR1LT5zZWN1cml0eUxldmVsOwogICAgICAgIHBhcm1zLnNjb3BlZFBkdSA9IHNwZHVfYnVmOwogICAgICAgIHBhcm1zLnNjb3BlZFBkdUxlbiA9IHNwZHVfbGVuOwogICAgICAgIHBhcm1zLnNlY1N0YXRlUmVmID0gcGR1LT5zZWN1cml0eVN0YXRlUmVmOwogICAgICAgIHBhcm1zLnNlY1BhcmFtcyA9IHNlY19wYXJhbXM7CiAgICAgICAgcGFybXMuc2VjUGFyYW1zTGVuID0gJnNlY19wYXJhbXNfbGVuOwogICAgICAgIHBhcm1zLndob2xlTXNnID0gJmNwOwogICAgICAgIHBhcm1zLndob2xlTXNnTGVuID0gb3V0X2xlbmd0aDsKICAgICAgICBwYXJtcy5zZXNzaW9uID0gc2Vzc2lvbjsKICAgICAgICBwYXJtcy5wZHUgPSBwZHU7CiAgICAgICAgcmVzdWx0ID0gKCpzcHRyLT5lbmNvZGVfZm9yd2FyZCkgKCZwYXJtcyk7CiAgICB9IGVsc2UgewogICAgICAgIGlmICghc3B0cikgewogICAgICAgICAgICBzbm1wX2xvZyhMT0dfRVJSLCAibm8gc3VjaCBzZWN1cml0eSBzZXJ2aWNlIGF2YWlsYWJsZTogJWRcbiIsCiAgICAgICAgICAgICAgICAgICAgIHBkdS0+c2VjdXJpdHlNb2RlbCk7CiAgICAgICAgfSBlbHNlIGlmICghc3B0ci0+ZW5jb2RlX2ZvcndhcmQpIHsKICAgICAgICAgICAgc25tcF9sb2coTE9HX0VSUiwKICAgICAgICAgICAgICAgICAgICAgInNlY3VyaXR5IHNlcnZpY2UgJWQgZG9lc24ndCBzdXBwb3J0IGZvcndhcmQgb3V0IGVuY29kaW5nLlxuIiwKICAgICAgICAgICAgICAgICAgICAgcGR1LT5zZWN1cml0eU1vZGVsKTsKICAgICAgICB9CiAgICAgICAgcmVzdWx0ID0gLTE7CiAgICB9CiAgICBERUJVR0lOREVOVExFU1MoKTsKICAgIHJldHVybiByZXN1bHQ7Cgp9ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIGVuZCBzbm1wdjNfcGFja2V0X2J1aWxkKCkgKi8KCgovKgogKiBUYWtlcyBhIHNlc3Npb24gYW5kIGEgcGR1IGFuZCBzZXJpYWxpemVzIHRoZSBBU04gUERVIGludG8gdGhlIGFyZWEKICogcG9pbnRlZCB0byBieSAqcGt0LiAgKnBrdF9sZW4gaXMgdGhlIHNpemUgb2YgdGhlIGRhdGEgYXJlYSBhdmFpbGFibGUuCiAqIFJldHVybnMgdGhlIGxlbmd0aCBvZiB0aGUgY29tcGxldGVkIHBhY2tldCBpbiAqb2Zmc2V0LiAgSWYgYW55IGVycm9ycwogKiBvY2N1ciwgLTEgaXMgcmV0dXJuZWQuICBJZiBhbGwgZ29lcyB3ZWxsLCAwIGlzIHJldHVybmVkLgogKi8KCnN0YXRpYyBpbnQKX3NubXBfYnVpbGQodV9jaGFyICoqIHBrdCwgc2l6ZV90ICogcGt0X2xlbiwgc2l6ZV90ICogb2Zmc2V0LAogICAgICAgICAgICBuZXRzbm1wX3Nlc3Npb24gKiBzZXNzaW9uLCBuZXRzbm1wX3BkdSAqcGR1KQp7CiNpZiAhZGVmaW5lZChORVRTTk1QX0RJU0FCTEVfU05NUFYxKSB8fCAhZGVmaW5lZChORVRTTk1QX0RJU0FCTEVfU05NUFYyQykKICAgIHVfY2hhciAgICAgICAgICpoMGUgPSAwOwogICAgc2l6ZV90ICAgICAgICAgIHN0YXJ0X29mZnNldCA9ICpvZmZzZXQ7CiAgICBsb25nICAgICAgICAgICAgdmVyc2lvbjsKICAgIGludCAgICAgICAgICAgICByYyA9IDA7CiNlbmRpZiAvKiBzdXBwb3J0IGZvciBjb21tdW5pdHkgYmFzZWQgU05NUCAqLwogICAgCiAgICB1X2NoYXIgICAgICAgICAqY3A7CiAgICBzaXplX3QgICAgICAgICAgbGVuZ3RoOwoKICAgIHNlc3Npb24tPnNfc25tcF9lcnJubyA9IDA7CiAgICBzZXNzaW9uLT5zX2Vycm5vID0gMDsKCiAgICBpZiAocGR1LT52ZXJzaW9uID09IFNOTVBfVkVSU0lPTl8zKSB7CiAgICAgICAgcmV0dXJuIHNubXB2M19idWlsZChwa3QsIHBrdF9sZW4sIG9mZnNldCwgc2Vzc2lvbiwgcGR1KTsKICAgIH0KCiAgICBzd2l0Y2ggKHBkdS0+Y29tbWFuZCkgewogICAgY2FzZSBTTk1QX01TR19SRVNQT05TRToKICAgICAgICBuZXRzbm1wX2Fzc2VydCgwID09IChwZHUtPmZsYWdzICYgVUNEX01TR19GTEFHX0VYUEVDVF9SRVNQT05TRSkpOwogICAgICAgIC8qCiAgICAgICAgICogRmFsbHRocm91Z2ggCiAgICAgICAgICovCiAgICBjYXNlIFNOTVBfTVNHX0dFVDoKICAgIGNhc2UgU05NUF9NU0dfR0VUTkVYVDoKICAgIGNhc2UgU05NUF9NU0dfU0VUOgogICAgICAgIC8qCiAgICAgICAgICogYWxsIHZlcnNpb25zIHN1cHBvcnQgdGhlc2UgUERVIHR5cGVzIAogICAgICAgICAqLwogICAgICAgIC8qCiAgICAgICAgICogaW5pdGlhbGl6ZSBkZWZhdWx0ZWQgUERVIGZpZWxkcyAKICAgICAgICAgKi8KCiAgICAgICAgaWYgKHBkdS0+ZXJyc3RhdCA9PSBTTk1QX0RFRkFVTFRfRVJSU1RBVCkKICAgICAgICAgICAgcGR1LT5lcnJzdGF0ID0gMDsKICAgICAgICBpZiAocGR1LT5lcnJpbmRleCA9PSBTTk1QX0RFRkFVTFRfRVJSSU5ERVgpCiAgICAgICAgICAgIHBkdS0+ZXJyaW5kZXggPSAwOwogICAgICAgIGJyZWFrOwoKICAgIGNhc2UgU05NUF9NU0dfVFJBUDI6CiAgICAgICAgbmV0c25tcF9hc3NlcnQoMCA9PSAocGR1LT5mbGFncyAmIFVDRF9NU0dfRkxBR19FWFBFQ1RfUkVTUE9OU0UpKTsKICAgICAgICAvKgogICAgICAgICAqIEZhbGx0aHJvdWdoIAogICAgICAgICAqLwogICAgY2FzZSBTTk1QX01TR19JTkZPUk06CiNpZm5kZWYgTkVUU05NUF9ESVNBQkxFX1NOTVBWMQogICAgICAgIC8qCiAgICAgICAgICogbm90IHN1cHBvcnRlZCBpbiBTTk1QdjEgYW5kIFNOTVBzZWMgCiAgICAgICAgICovCiAgICAgICAgaWYgKHBkdS0+dmVyc2lvbiA9PSBTTk1QX1ZFUlNJT05fMSkgewogICAgICAgICAgICBzZXNzaW9uLT5zX3NubXBfZXJybm8gPSBTTk1QRVJSX1YyX0lOX1YxOwogICAgICAgICAgICByZXR1cm4gLTE7CiAgICAgICAgfQojZW5kaWYKICAgICAgICBpZiAocGR1LT5lcnJzdGF0ID09IFNOTVBfREVGQVVMVF9FUlJTVEFUKQogICAgICAgICAgICBwZHUtPmVycnN0YXQgPSAwOwogICAgICAgIGlmIChwZHUtPmVycmluZGV4ID09IFNOTVBfREVGQVVMVF9FUlJJTkRFWCkKICAgICAgICAgICAgcGR1LT5lcnJpbmRleCA9IDA7CiAgICAgICAgYnJlYWs7CgogICAgY2FzZSBTTk1QX01TR19HRVRCVUxLOgogICAgICAgIC8qCiAgICAgICAgICogbm90IHN1cHBvcnRlZCBpbiBTTk1QdjEgYW5kIFNOTVBzZWMgCiAgICAgICAgICovCiNpZm5kZWYgTkVUU05NUF9ESVNBQkxFX1NOTVBWMQogICAgICAgIGlmIChwZHUtPnZlcnNpb24gPT0gU05NUF9WRVJTSU9OXzEpIHsKICAgICAgICAgICAgc2Vzc2lvbi0+c19zbm1wX2Vycm5vID0gU05NUEVSUl9WMl9JTl9WMTsKICAgICAgICAgICAgcmV0dXJuIC0xOwogICAgICAgIH0KI2VuZGlmCiAgICAgICAgaWYgKHBkdS0+bWF4X3JlcGV0aXRpb25zIDwgMCkgewogICAgICAgICAgICBzZXNzaW9uLT5zX3NubXBfZXJybm8gPSBTTk1QRVJSX0JBRF9SRVBFVElUSU9OUzsKICAgICAgICAgICAgcmV0dXJuIC0xOwogICAgICAgIH0KICAgICAgICBpZiAocGR1LT5ub25fcmVwZWF0ZXJzIDwgMCkgewogICAgICAgICAgICBzZXNzaW9uLT5zX3NubXBfZXJybm8gPSBTTk1QRVJSX0JBRF9SRVBFQVRFUlM7CiAgICAgICAgICAgIHJldHVybiAtMTsKICAgICAgICB9CiAgICAgICAgYnJlYWs7CgogICAgY2FzZSBTTk1QX01TR19UUkFQOgogICAgICAgIC8qCiAgICAgICAgICogKm9ubHkqIHN1cHBvcnRlZCBpbiBTTk1QdjEgYW5kIFNOTVBzZWMgCiAgICAgICAgICovCiNpZm5kZWYgTkVUU05NUF9ESVNBQkxFX1NOTVBWMQogICAgICAgIGlmIChwZHUtPnZlcnNpb24gIT0gU05NUF9WRVJTSU9OXzEpIHsKICAgICAgICAgICAgc2Vzc2lvbi0+c19zbm1wX2Vycm5vID0gU05NUEVSUl9WMV9JTl9WMjsKICAgICAgICAgICAgcmV0dXJuIC0xOwogICAgICAgIH0KI2VuZGlmCiAgICAgICAgLyoKICAgICAgICAgKiBpbml0aWFsaXplIGRlZmF1bHRlZCBUcmFwIFBEVSBmaWVsZHMgCiAgICAgICAgICovCiAgICAgICAgcGR1LT5yZXFpZCA9IDE7ICAgICAgICAgLyogZ2l2ZSBhIGJvZ3VzIG5vbi1lcnJvciByZXFpZCBmb3IgdHJhcHMgKi8KICAgICAgICBpZiAocGR1LT5lbnRlcnByaXNlX2xlbmd0aCA9PSBTTk1QX0RFRkFVTFRfRU5URVJQUklTRV9MRU5HVEgpIHsKICAgICAgICAgICAgcGR1LT5lbnRlcnByaXNlID0gKG9pZCAqKSBtYWxsb2Moc2l6ZW9mKERFRkFVTFRfRU5URVJQUklTRSkpOwogICAgICAgICAgICBpZiAocGR1LT5lbnRlcnByaXNlID09IE5VTEwpIHsKICAgICAgICAgICAgICAgIHNlc3Npb24tPnNfc25tcF9lcnJubyA9IFNOTVBFUlJfTUFMTE9DOwogICAgICAgICAgICAgICAgcmV0dXJuIC0xOwogICAgICAgICAgICB9CiAgICAgICAgICAgIG1lbW1vdmUocGR1LT5lbnRlcnByaXNlLCBERUZBVUxUX0VOVEVSUFJJU0UsCiAgICAgICAgICAgICAgICAgICAgc2l6ZW9mKERFRkFVTFRfRU5URVJQUklTRSkpOwogICAgICAgICAgICBwZHUtPmVudGVycHJpc2VfbGVuZ3RoID0KICAgICAgICAgICAgICAgIHNpemVvZihERUZBVUxUX0VOVEVSUFJJU0UpIC8gc2l6ZW9mKG9pZCk7CiAgICAgICAgfQogICAgICAgIGlmIChwZHUtPnRpbWUgPT0gU05NUF9ERUZBVUxUX1RJTUUpCiAgICAgICAgICAgIHBkdS0+dGltZSA9IERFRkFVTFRfVElNRTsKICAgICAgICAvKgogICAgICAgICAqIGRvbid0IGV4cGVjdCBhIHJlc3BvbnNlIAogICAgICAgICAqLwogICAgICAgIHBkdS0+ZmxhZ3MgJj0gKH5VQ0RfTVNHX0ZMQUdfRVhQRUNUX1JFU1BPTlNFKTsKICAgICAgICBicmVhazsKCiAgICBjYXNlIFNOTVBfTVNHX1JFUE9SVDogICAgICAvKiBTTk1QdjMgb25seSAqLwogICAgZGVmYXVsdDoKICAgICAgICBzZXNzaW9uLT5zX3NubXBfZXJybm8gPSBTTk1QRVJSX1VOS05PV05fUERVOwogICAgICAgIHJldHVybiAtMTsKICAgIH0KCiAgICAvKgogICAgICogc2F2ZSBsZW5ndGggCiAgICAgKi8KICAgIGxlbmd0aCA9ICpwa3RfbGVuOwoKICAgIC8qCiAgICAgKiBzZXR1cCBhZG1pbmlzdHJhdGl2ZSBmaWVsZHMgYmFzZWQgb24gdmVyc2lvbiAKICAgICAqLwogICAgLyoKICAgICAqIGJ1aWxkIHRoZSBtZXNzYWdlIHdyYXBwZXIgYW5kIGFsbCB0aGUgYWRtaW5pc3RyYXRpdmUgZmllbGRzCiAgICAgKiB1cHRvIHRoZSBQRFUgc2VxdWVuY2UKICAgICAqIChub3RlIHRoYXQgYWN0dWFsIGxlbmd0aCBvZiBtZXNzYWdlIHdpbGwgYmUgaW5zZXJ0ZWQgbGF0ZXIpIAogICAgICovCiAgICBzd2l0Y2ggKHBkdS0+dmVyc2lvbikgewojaWZuZGVmIE5FVFNOTVBfRElTQUJMRV9TTk1QVjEKICAgIGNhc2UgU05NUF9WRVJTSU9OXzE6CiNlbmRpZgojaWZuZGVmIE5FVFNOTVBfRElTQUJMRV9TTk1QVjJDCiAgICBjYXNlIFNOTVBfVkVSU0lPTl8yYzoKI2VuZGlmCiNpZiAhZGVmaW5lZChORVRTTk1QX0RJU0FCTEVfU05NUFYxKSB8fCAhZGVmaW5lZChORVRTTk1QX0RJU0FCTEVfU05NUFYyQykKI2lmZGVmIE5FVFNOTVBfTk9fWkVST0xFTkdUSF9DT01NVU5JVFkKICAgICAgICBpZiAocGR1LT5jb21tdW5pdHlfbGVuID09IDApIHsKICAgICAgICAgICAgaWYgKHNlc3Npb24tPmNvbW11bml0eV9sZW4gPT0gMCkgewogICAgICAgICAgICAgICAgc2Vzc2lvbi0+c19zbm1wX2Vycm5vID0gU05NUEVSUl9CQURfQ09NTVVOSVRZOwogICAgICAgICAgICAgICAgcmV0dXJuIC0xOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHBkdS0+Y29tbXVuaXR5ID0gKHVfY2hhciAqKSBtYWxsb2Moc2Vzc2lvbi0+Y29tbXVuaXR5X2xlbik7CiAgICAgICAgICAgIGlmIChwZHUtPmNvbW11bml0eSA9PSBOVUxMKSB7CiAgICAgICAgICAgICAgICBzZXNzaW9uLT5zX3NubXBfZXJybm8gPSBTTk1QRVJSX01BTExPQzsKICAgICAgICAgICAgICAgIHJldHVybiAtMTsKICAgICAgICAgICAgfQogICAgICAgICAgICBtZW1tb3ZlKHBkdS0+Y29tbXVuaXR5LAogICAgICAgICAgICAgICAgICAgIHNlc3Npb24tPmNvbW11bml0eSwgc2Vzc2lvbi0+Y29tbXVuaXR5X2xlbik7CiAgICAgICAgICAgIHBkdS0+Y29tbXVuaXR5X2xlbiA9IHNlc3Npb24tPmNvbW11bml0eV9sZW47CiAgICAgICAgfQojZWxzZSAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qICFORVRTTk1QX05PX1pFUk9MRU5HVEhfQ09NTVVOSVRZICovCiAgICAgICAgaWYgKHBkdS0+Y29tbXVuaXR5X2xlbiA9PSAwICYmIHBkdS0+Y29tbWFuZCAhPSBTTk1QX01TR19SRVNQT05TRSkgewogICAgICAgICAgICAvKgogICAgICAgICAgICAgKiBjb3B5IHNlc3Npb24gY29tbXVuaXR5IGV4YWN0bHkgdG8gcGR1IGNvbW11bml0eSAKICAgICAgICAgICAgICovCiAgICAgICAgICAgIGlmICgwID09IHNlc3Npb24tPmNvbW11bml0eV9sZW4pIHsKICAgICAgICAgICAgICAgIFNOTVBfRlJFRShwZHUtPmNvbW11bml0eSk7CiAgICAgICAgICAgICAgICBwZHUtPmNvbW11bml0eSA9IE5VTEw7CiAgICAgICAgICAgIH0gZWxzZSBpZiAocGR1LT5jb21tdW5pdHlfbGVuID09IHNlc3Npb24tPmNvbW11bml0eV9sZW4pIHsKICAgICAgICAgICAgICAgIG1lbW1vdmUocGR1LT5jb21tdW5pdHksCiAgICAgICAgICAgICAgICAgICAgICAgIHNlc3Npb24tPmNvbW11bml0eSwgc2Vzc2lvbi0+Y29tbXVuaXR5X2xlbik7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBTTk1QX0ZSRUUocGR1LT5jb21tdW5pdHkpOwogICAgICAgICAgICAgICAgcGR1LT5jb21tdW5pdHkgPSAodV9jaGFyICopIG1hbGxvYyhzZXNzaW9uLT5jb21tdW5pdHlfbGVuKTsKICAgICAgICAgICAgICAgIGlmIChwZHUtPmNvbW11bml0eSA9PSBOVUxMKSB7CiAgICAgICAgICAgICAgICAgICAgc2Vzc2lvbi0+c19zbm1wX2Vycm5vID0gU05NUEVSUl9NQUxMT0M7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIC0xOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgbWVtbW92ZShwZHUtPmNvbW11bml0eSwKICAgICAgICAgICAgICAgICAgICAgICAgc2Vzc2lvbi0+Y29tbXVuaXR5LCBzZXNzaW9uLT5jb21tdW5pdHlfbGVuKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBwZHUtPmNvbW11bml0eV9sZW4gPSBzZXNzaW9uLT5jb21tdW5pdHlfbGVuOwogICAgICAgIH0KI2VuZGlmICAgICAgICAgICAgICAgICAgICAgICAgICAvKiAhTkVUU05NUF9OT19aRVJPTEVOR1RIX0NPTU1VTklUWSAqLwoKICAgICAgICBERUJVR01TR1RMKCgic25tcF9zZW5kIiwgIkJ1aWxkaW5nIFNOTVB2JWQgbWVzc2FnZS4uLlxuIiwKICAgICAgICAgICAgICAgICAgICAoMSArIHBkdS0+dmVyc2lvbikpKTsKI2lmZGVmIE5FVFNOTVBfVVNFX1JFVkVSU0VfQVNORU5DT0RJTkcKICAgICAgICBpZiAobmV0c25tcF9kc19nZXRfYm9vbGVhbihORVRTTk1QX0RTX0xJQlJBUllfSUQsIE5FVFNOTVBfRFNfTElCX1JFVkVSU0VfRU5DT0RFKSkgewogICAgICAgICAgICBERUJVR1BSSU5UUERVVFlQRSgic2VuZCIsIHBkdS0+Y29tbWFuZCk7CiAgICAgICAgICAgIHJjID0gc25tcF9wZHVfcmVhbGxvY19yYnVpbGQocGt0LCBwa3RfbGVuLCBvZmZzZXQsIHBkdSk7CiAgICAgICAgICAgIGlmIChyYyA9PSAwKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gLTE7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIERFQlVHRFVNUEhFQURFUigic2VuZCIsICJDb21tdW5pdHkgU3RyaW5nIik7CiAgICAgICAgICAgIHJjID0gYXNuX3JlYWxsb2NfcmJ1aWxkX3N0cmluZyhwa3QsIHBrdF9sZW4sIG9mZnNldCwgMSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICh1X2NoYXIpIChBU05fVU5JVkVSU0FMIHwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBU05fUFJJTUlUSVZFIHwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBU05fT0NURVRfU1RSKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBkdS0+Y29tbXVuaXR5LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGR1LT5jb21tdW5pdHlfbGVuKTsKICAgICAgICAgICAgREVCVUdJTkRFTlRMRVNTKCk7CiAgICAgICAgICAgIGlmIChyYyA9PSAwKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gLTE7CiAgICAgICAgICAgIH0KCgogICAgICAgICAgICAvKgogICAgICAgICAgICAgKiBTdG9yZSB0aGUgdmVyc2lvbiBmaWVsZC4gIAogICAgICAgICAgICAgKi8KICAgICAgICAgICAgREVCVUdEVU1QSEVBREVSKCJzZW5kIiwgIlNOTVAgVmVyc2lvbiBOdW1iZXIiKTsKCiAgICAgICAgICAgIHZlcnNpb24gPSBwZHUtPnZlcnNpb247CiAgICAgICAgICAgIHJjID0gYXNuX3JlYWxsb2NfcmJ1aWxkX2ludChwa3QsIHBrdF9sZW4sIG9mZnNldCwgMSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICh1X2NoYXIpIChBU05fVU5JVkVSU0FMIHwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBU05fUFJJTUlUSVZFIHwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBU05fSU5URUdFUiksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAobG9uZyAqKSAmdmVyc2lvbiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNpemVvZih2ZXJzaW9uKSk7CiAgICAgICAgICAgIERFQlVHSU5ERU5UTEVTUygpOwogICAgICAgICAgICBpZiAocmMgPT0gMCkgewogICAgICAgICAgICAgICAgcmV0dXJuIC0xOwogICAgICAgICAgICB9CgogICAgICAgICAgICAvKgogICAgICAgICAgICAgKiBCdWlsZCB0aGUgZmluYWwgc2VxdWVuY2UuICAKICAgICAgICAgICAgICovCiNpZm5kZWYgTkVUU05NUF9ESVNBQkxFX1NOTVBWMQogICAgICAgICAgICBpZiAocGR1LT52ZXJzaW9uID09IFNOTVBfVkVSU0lPTl8xKSB7CiAgICAgICAgICAgICAgICBERUJVR0RVTVBTRUNUSU9OKCJzZW5kIiwgIlNOTVB2MSBNZXNzYWdlIik7CiAgICAgICAgICAgIH0gZWxzZSB7CiNlbmRpZgogICAgICAgICAgICAgICAgREVCVUdEVU1QU0VDVElPTigic2VuZCIsICJTTk1QdjJjIE1lc3NhZ2UiKTsKI2lmbmRlZiBORVRTTk1QX0RJU0FCTEVfU05NUFYxCiAgICAgICAgICAgIH0KI2VuZGlmCiAgICAgICAgICAgIHJjID0gYXNuX3JlYWxsb2NfcmJ1aWxkX3NlcXVlbmNlKHBrdCwgcGt0X2xlbiwgb2Zmc2V0LCAxLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAodV9jaGFyKSAoQVNOX1NFUVVFTkNFIHwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEFTTl9DT05TVFJVQ1RPUiksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICpvZmZzZXQgLSBzdGFydF9vZmZzZXQpOwogICAgICAgICAgICBERUJVR0lOREVOVExFU1MoKTsKCiAgICAgICAgICAgIGlmIChyYyA9PSAwKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gLTE7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIDA7CiAgICAgICAgfSBlbHNlIHsKCiNlbmRpZiAgICAgICAgICAgICAgICAgICAgICAgICAgLyogTkVUU05NUF9VU0VfUkVWRVJTRV9BU05FTkNPRElORyAqLwogICAgICAgICAgICAvKgogICAgICAgICAgICAgKiBTYXZlIGN1cnJlbnQgbG9jYXRpb24gYW5kIGJ1aWxkIFNFUVVFTkNFIHRhZyBhbmQgbGVuZ3RoCiAgICAgICAgICAgICAqIHBsYWNlaG9sZGVyIGZvciBTTk1QIG1lc3NhZ2Ugc2VxdWVuY2UKICAgICAgICAgICAgICogKGFjdHVhbCBsZW5ndGggd2lsbCBiZSBpbnNlcnRlZCBsYXRlcikgCiAgICAgICAgICAgICAqLwogICAgICAgICAgICBjcCA9IGFzbl9idWlsZF9zZXF1ZW5jZSgqcGt0LCBwa3RfbGVuLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAodV9jaGFyKSAoQVNOX1NFUVVFTkNFIHwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEFTTl9DT05TVFJVQ1RPUiksIDApOwogICAgICAgICAgICBpZiAoY3AgPT0gTlVMTCkgewogICAgICAgICAgICAgICAgcmV0dXJuIC0xOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGgwZSA9IGNwOwoKI2lmbmRlZiBORVRTTk1QX0RJU0FCTEVfU05NUFYxCiAgICAgICAgICAgIGlmIChwZHUtPnZlcnNpb24gPT0gU05NUF9WRVJTSU9OXzEpIHsKICAgICAgICAgICAgICAgIERFQlVHRFVNUFNFQ1RJT04oInNlbmQiLCAiU05NUHYxIE1lc3NhZ2UiKTsKICAgICAgICAgICAgfSBlbHNlIHsKI2VuZGlmCiAgICAgICAgICAgICAgICBERUJVR0RVTVBTRUNUSU9OKCJzZW5kIiwgIlNOTVB2MmMgTWVzc2FnZSIpOwojaWZuZGVmIE5FVFNOTVBfRElTQUJMRV9TTk1QVjEKICAgICAgICAgICAgfQojZW5kaWYKCiAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAqIHN0b3JlIHRoZSB2ZXJzaW9uIGZpZWxkIAogICAgICAgICAgICAgKi8KICAgICAgICAgICAgREVCVUdEVU1QSEVBREVSKCJzZW5kIiwgIlNOTVAgVmVyc2lvbiBOdW1iZXIiKTsKCiAgICAgICAgICAgIHZlcnNpb24gPSBwZHUtPnZlcnNpb247CiAgICAgICAgICAgIGNwID0gYXNuX2J1aWxkX2ludChjcCwgcGt0X2xlbiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICh1X2NoYXIpIChBU05fVU5JVkVSU0FMIHwgQVNOX1BSSU1JVElWRSB8CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQVNOX0lOVEVHRVIpLCAobG9uZyAqKSAmdmVyc2lvbiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNpemVvZih2ZXJzaW9uKSk7CiAgICAgICAgICAgIERFQlVHSU5ERU5UTEVTUygpOwogICAgICAgICAgICBpZiAoY3AgPT0gTlVMTCkKICAgICAgICAgICAgICAgIHJldHVybiAtMTsKCiAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAqIHN0b3JlIHRoZSBjb21tdW5pdHkgc3RyaW5nIAogICAgICAgICAgICAgKi8KICAgICAgICAgICAgREVCVUdEVU1QSEVBREVSKCJzZW5kIiwgIkNvbW11bml0eSBTdHJpbmciKTsKICAgICAgICAgICAgY3AgPSBhc25fYnVpbGRfc3RyaW5nKGNwLCBwa3RfbGVuLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKHVfY2hhcikgKEFTTl9VTklWRVJTQUwgfCBBU05fUFJJTUlUSVZFIHwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBU05fT0NURVRfU1RSKSwgcGR1LT5jb21tdW5pdHksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwZHUtPmNvbW11bml0eV9sZW4pOwogICAgICAgICAgICBERUJVR0lOREVOVExFU1MoKTsKICAgICAgICAgICAgaWYgKGNwID09IE5VTEwpCiAgICAgICAgICAgICAgICByZXR1cm4gLTE7CiAgICAgICAgICAgIGJyZWFrOwoKI2lmZGVmIE5FVFNOTVBfVVNFX1JFVkVSU0VfQVNORU5DT0RJTkcKICAgICAgICB9CiNlbmRpZiAgICAgICAgICAgICAgICAgICAgICAgICAgLyogTkVUU05NUF9VU0VfUkVWRVJTRV9BU05FTkNPRElORyAqLwogICAgICAgIGJyZWFrOwojZW5kaWYgLyogc3VwcG9ydCBmb3IgY29tbXVuaXR5IGJhc2VkIFNOTVAgKi8KICAgIGNhc2UgU05NUF9WRVJTSU9OXzJwOgogICAgY2FzZSBTTk1QX1ZFUlNJT05fc2VjOgogICAgY2FzZSBTTk1QX1ZFUlNJT05fMnU6CiAgICBjYXNlIFNOTVBfVkVSU0lPTl8yc3RhcjoKICAgIGRlZmF1bHQ6CiAgICAgICAgc2Vzc2lvbi0+c19zbm1wX2Vycm5vID0gU05NUEVSUl9CQURfVkVSU0lPTjsKICAgICAgICByZXR1cm4gLTE7CiAgICB9CgogICAgREVCVUdQUklOVFBEVVRZUEUoInNlbmQiLCBwZHUtPmNvbW1hbmQpOwogICAgY3AgPSBzbm1wX3BkdV9idWlsZChwZHUsIGNwLCBwa3RfbGVuKTsKICAgIERFQlVHSU5ERU5UQUREKC00KTsgICAgICAgICAvKiByZXR1cm4gZnJvbSBlbnRpcmUgdjEvdjJjIG1lc3NhZ2UgKi8KICAgIGlmIChjcCA9PSBOVUxMKQogICAgICAgIHJldHVybiAtMTsKCiAgICAvKgogICAgICogaW5zZXJ0IHRoZSBhY3R1YWwgbGVuZ3RoIG9mIHRoZSBtZXNzYWdlIHNlcXVlbmNlIAogICAgICovCiAgICBzd2l0Y2ggKHBkdS0+dmVyc2lvbikgewojaWZuZGVmIE5FVFNOTVBfRElTQUJMRV9TTk1QVjEKICAgIGNhc2UgU05NUF9WRVJTSU9OXzE6CiNlbmRpZgojaWZuZGVmIE5FVFNOTVBfRElTQUJMRV9TTk1QVjJDCiAgICBjYXNlIFNOTVBfVkVSU0lPTl8yYzoKI2VuZGlmCiNpZiAhZGVmaW5lZChORVRTTk1QX0RJU0FCTEVfU05NUFYxKSB8fCAhZGVmaW5lZChORVRTTk1QX0RJU0FCTEVfU05NUFYyQykKICAgICAgICBhc25fYnVpbGRfc2VxdWVuY2UoKnBrdCwgJmxlbmd0aCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgKHVfY2hhcikgKEFTTl9TRVFVRU5DRSB8IEFTTl9DT05TVFJVQ1RPUiksCiAgICAgICAgICAgICAgICAgICAgICAgICAgIGNwIC0gaDBlKTsKICAgICAgICBicmVhazsKI2VuZGlmIC8qIHN1cHBvcnQgZm9yIGNvbW11bml0eSBiYXNlZCBTTk1QICovCgogICAgY2FzZSBTTk1QX1ZFUlNJT05fMnA6CiAgICBjYXNlIFNOTVBfVkVSU0lPTl9zZWM6CiAgICBjYXNlIFNOTVBfVkVSU0lPTl8ydToKICAgIGNhc2UgU05NUF9WRVJTSU9OXzJzdGFyOgogICAgZGVmYXVsdDoKICAgICAgICBzZXNzaW9uLT5zX3NubXBfZXJybm8gPSBTTk1QRVJSX0JBRF9WRVJTSU9OOwogICAgICAgIHJldHVybiAtMTsKICAgIH0KICAgICpwa3RfbGVuID0gY3AgLSAqcGt0OwogICAgcmV0dXJuIDA7Cn0KCmludApzbm1wX2J1aWxkKHVfY2hhciAqKiBwa3QsIHNpemVfdCAqIHBrdF9sZW4sIHNpemVfdCAqIG9mZnNldCwKICAgICAgICAgICBuZXRzbm1wX3Nlc3Npb24gKiBwc3MsIG5ldHNubXBfcGR1ICpwZHUpCnsKICAgIGludCAgICAgICAgICAgICByYzsKICAgIHJjID0gX3NubXBfYnVpbGQocGt0LCBwa3RfbGVuLCBvZmZzZXQsIHBzcywgcGR1KTsKICAgIGlmIChyYykgewogICAgICAgIGlmICghcHNzLT5zX3NubXBfZXJybm8pIHsKICAgICAgICAgICAgc25tcF9sb2coTE9HX0VSUiwgInNubXBfYnVpbGQ6IHVua25vd24gZmFpbHVyZVxuIik7CiAgICAgICAgICAgIHBzcy0+c19zbm1wX2Vycm5vID0gU05NUEVSUl9CQURfQVNOMV9CVUlMRDsKICAgICAgICB9CiAgICAgICAgU0VUX1NOTVBfRVJST1IocHNzLT5zX3NubXBfZXJybm8pOwogICAgICAgIHJjID0gLTE7CiAgICB9CiAgICByZXR1cm4gcmM7Cn0KCi8qCiAqIG9uIGVycm9yLCByZXR1cm5zIE5VTEwgKGxpa2VseSBhbiBlbmNvZGluZyBwcm9ibGVtKS4gCiAqLwp1X2NoYXIgICAgICAgICAqCnNubXBfcGR1X2J1aWxkKG5ldHNubXBfcGR1ICpwZHUsIHVfY2hhciAqIGNwLCBzaXplX3QgKiBvdXRfbGVuZ3RoKQp7CiAgICB1X2NoYXIgICAgICAgICAqaDEsICpoMWUsICpoMiwgKmgyZTsKICAgIG5ldHNubXBfdmFyaWFibGVfbGlzdCAqdnA7CiAgICBzaXplX3QgICAgICAgICAgbGVuZ3RoOwoKICAgIGxlbmd0aCA9ICpvdXRfbGVuZ3RoOwogICAgLyoKICAgICAqIFNhdmUgY3VycmVudCBsb2NhdGlvbiBhbmQgYnVpbGQgUERVIHRhZyBhbmQgbGVuZ3RoIHBsYWNlaG9sZGVyCiAgICAgKiAoYWN0dWFsIGxlbmd0aCB3aWxsIGJlIGluc2VydGVkIGxhdGVyKSAKICAgICAqLwogICAgaDEgPSBjcDsKICAgIGNwID0gYXNuX2J1aWxkX3NlcXVlbmNlKGNwLCBvdXRfbGVuZ3RoLCAodV9jaGFyKSBwZHUtPmNvbW1hbmQsIDApOwogICAgaWYgKGNwID09IE5VTEwpCiAgICAgICAgcmV0dXJuIE5VTEw7CiAgICBoMWUgPSBjcDsKCiAgICAvKgogICAgICogc3RvcmUgZmllbGRzIGluIHRoZSBQRFUgcHJlY2VlZGluZyB0aGUgdmFyaWFibGUtYmluZGluZ3Mgc2VxdWVuY2UgCiAgICAgKi8KICAgIGlmIChwZHUtPmNvbW1hbmQgIT0gU05NUF9NU0dfVFJBUCkgewogICAgICAgIC8qCiAgICAgICAgICogUERVIGlzIG5vdCBhbiBTTk1QdjEgdHJhcCAKICAgICAgICAgKi8KCiAgICAgICAgREVCVUdEVU1QSEVBREVSKCJzZW5kIiwgInJlcXVlc3RfaWQiKTsKICAgICAgICAvKgogICAgICAgICAqIHJlcXVlc3QgaWQgCiAgICAgICAgICovCiAgICAgICAgY3AgPSBhc25fYnVpbGRfaW50KGNwLCBvdXRfbGVuZ3RoLAogICAgICAgICAgICAgICAgICAgICAgICAgICAodV9jaGFyKSAoQVNOX1VOSVZFUlNBTCB8IEFTTl9QUklNSVRJVkUgfAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQVNOX0lOVEVHRVIpLCAmcGR1LT5yZXFpZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgc2l6ZW9mKHBkdS0+cmVxaWQpKTsKICAgICAgICBERUJVR0lOREVOVExFU1MoKTsKICAgICAgICBpZiAoY3AgPT0gTlVMTCkKICAgICAgICAgICAgcmV0dXJuIE5VTEw7CgogICAgICAgIC8qCiAgICAgICAgICogZXJyb3Igc3RhdHVzIChnZXRidWxrIG5vbi1yZXBlYXRlcnMpIAogICAgICAgICAqLwogICAgICAgIERFQlVHRFVNUEhFQURFUigic2VuZCIsICJlcnJvciBzdGF0dXMiKTsKICAgICAgICBjcCA9IGFzbl9idWlsZF9pbnQoY3AsIG91dF9sZW5ndGgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICh1X2NoYXIpIChBU05fVU5JVkVSU0FMIHwgQVNOX1BSSU1JVElWRSB8CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBU05fSU5URUdFUiksICZwZHUtPmVycnN0YXQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIHNpemVvZihwZHUtPmVycnN0YXQpKTsKICAgICAgICBERUJVR0lOREVOVExFU1MoKTsKICAgICAgICBpZiAoY3AgPT0gTlVMTCkKICAgICAgICAgICAgcmV0dXJuIE5VTEw7CgogICAgICAgIC8qCiAgICAgICAgICogZXJyb3IgaW5kZXggKGdldGJ1bGsgbWF4LXJlcGV0aXRpb25zKSAKICAgICAgICAgKi8KICAgICAgICBERUJVR0RVTVBIRUFERVIoInNlbmQiLCAiZXJyb3IgaW5kZXgiKTsKICAgICAgICBjcCA9IGFzbl9idWlsZF9pbnQoY3AsIG91dF9sZW5ndGgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICh1X2NoYXIpIChBU05fVU5JVkVSU0FMIHwgQVNOX1BSSU1JVElWRSB8CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBU05fSU5URUdFUiksICZwZHUtPmVycmluZGV4LAogICAgICAgICAgICAgICAgICAgICAgICAgICBzaXplb2YocGR1LT5lcnJpbmRleCkpOwogICAgICAgIERFQlVHSU5ERU5UTEVTUygpOwogICAgICAgIGlmIChjcCA9PSBOVUxMKQogICAgICAgICAgICByZXR1cm4gTlVMTDsKICAgIH0gZWxzZSB7CiAgICAgICAgLyoKICAgICAgICAgKiBhbiBTTk1QdjEgdHJhcCBQRFUgCiAgICAgICAgICovCgogICAgICAgIC8qCiAgICAgICAgICogZW50ZXJwcmlzZSAKICAgICAgICAgKi8KICAgICAgICBERUJVR0RVTVBIRUFERVIoInNlbmQiLCAiZW50ZXJwcmlzZSBPQkpJRCIpOwogICAgICAgIGNwID0gYXNuX2J1aWxkX29iamlkKGNwLCBvdXRfbGVuZ3RoLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICh1X2NoYXIpIChBU05fVU5JVkVSU0FMIHwgQVNOX1BSSU1JVElWRSB8CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEFTTl9PQkpFQ1RfSUQpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIChvaWQgKikgcGR1LT5lbnRlcnByaXNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBkdS0+ZW50ZXJwcmlzZV9sZW5ndGgpOwogICAgICAgIERFQlVHSU5ERU5UTEVTUygpOwogICAgICAgIGlmIChjcCA9PSBOVUxMKQogICAgICAgICAgICByZXR1cm4gTlVMTDsKCiAgICAgICAgLyoKICAgICAgICAgKiBhZ2VudC1hZGRyIAogICAgICAgICAqLwogICAgICAgIERFQlVHRFVNUEhFQURFUigic2VuZCIsICJhZ2VudCBBZGRyZXNzIik7CiAgICAgICAgY3AgPSBhc25fYnVpbGRfc3RyaW5nKGNwLCBvdXRfbGVuZ3RoLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAodV9jaGFyKSAoQVNOX0lQQUREUkVTUyB8IEFTTl9QUklNSVRJVkUpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAodV9jaGFyICopIHBkdS0+YWdlbnRfYWRkciwgNCk7CiAgICAgICAgREVCVUdJTkRFTlRMRVNTKCk7CiAgICAgICAgaWYgKGNwID09IE5VTEwpCiAgICAgICAgICAgIHJldHVybiBOVUxMOwoKICAgICAgICAvKgogICAgICAgICAqIGdlbmVyaWMgdHJhcCAKICAgICAgICAgKi8KICAgICAgICBERUJVR0RVTVBIRUFERVIoInNlbmQiLCAiZ2VuZXJpYyB0cmFwIG51bWJlciIpOwogICAgICAgIGNwID0gYXNuX2J1aWxkX2ludChjcCwgb3V0X2xlbmd0aCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgKHVfY2hhcikgKEFTTl9VTklWRVJTQUwgfCBBU05fUFJJTUlUSVZFIHwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEFTTl9JTlRFR0VSKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgKGxvbmcgKikgJnBkdS0+dHJhcF90eXBlLAogICAgICAgICAgICAgICAgICAgICAgICAgICBzaXplb2YocGR1LT50cmFwX3R5cGUpKTsKICAgICAgICBERUJVR0lOREVOVExFU1MoKTsKICAgICAgICBpZiAoY3AgPT0gTlVMTCkKICAgICAgICAgICAgcmV0dXJuIE5VTEw7CgogICAgICAgIC8qCiAgICAgICAgICogc3BlY2lmaWMgdHJhcCAKICAgICAgICAgKi8KICAgICAgICBERUJVR0RVTVBIRUFERVIoInNlbmQiLCAic3BlY2lmaWMgdHJhcCBudW1iZXIiKTsKICAgICAgICBjcCA9IGFzbl9idWlsZF9pbnQoY3AsIG91dF9sZW5ndGgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICh1X2NoYXIpIChBU05fVU5JVkVSU0FMIHwgQVNOX1BSSU1JVElWRSB8CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBU05fSU5URUdFUiksCiAgICAgICAgICAgICAgICAgICAgICAgICAgIChsb25nICopICZwZHUtPnNwZWNpZmljX3R5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIHNpemVvZihwZHUtPnNwZWNpZmljX3R5cGUpKTsKICAgICAgICBERUJVR0lOREVOVExFU1MoKTsKICAgICAgICBpZiAoY3AgPT0gTlVMTCkKICAgICAgICAgICAgcmV0dXJuIE5VTEw7CgogICAgICAgIC8qCiAgICAgICAgICogdGltZXN0YW1wICAKICAgICAgICAgKi8KICAgICAgICBERUJVR0RVTVBIRUFERVIoInNlbmQiLCAidGltZXN0YW1wIik7CiAgICAgICAgY3AgPSBhc25fYnVpbGRfdW5zaWduZWRfaW50KGNwLCBvdXRfbGVuZ3RoLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAodV9jaGFyKSAoQVNOX1RJTUVUSUNLUyB8CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBU05fUFJJTUlUSVZFKSwgJnBkdS0+dGltZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2l6ZW9mKHBkdS0+dGltZSkpOwogICAgICAgIERFQlVHSU5ERU5UTEVTUygpOwogICAgICAgIGlmIChjcCA9PSBOVUxMKQogICAgICAgICAgICByZXR1cm4gTlVMTDsKICAgIH0KCiAgICAvKgogICAgICogU2F2ZSBjdXJyZW50IGxvY2F0aW9uIGFuZCBidWlsZCBTRVFVRU5DRSB0YWcgYW5kIGxlbmd0aCBwbGFjZWhvbGRlcgogICAgICogZm9yIHZhcmlhYmxlLWJpbmRpbmdzIHNlcXVlbmNlCiAgICAgKiAoYWN0dWFsIGxlbmd0aCB3aWxsIGJlIGluc2VydGVkIGxhdGVyKSAKICAgICAqLwogICAgaDIgPSBjcDsKICAgIGNwID0gYXNuX2J1aWxkX3NlcXVlbmNlKGNwLCBvdXRfbGVuZ3RoLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgKHVfY2hhcikgKEFTTl9TRVFVRU5DRSB8IEFTTl9DT05TVFJVQ1RPUiksIDApOwogICAgaWYgKGNwID09IE5VTEwpCiAgICAgICAgcmV0dXJuIE5VTEw7CiAgICBoMmUgPSBjcDsKCiAgICAvKgogICAgICogU3RvcmUgdmFyaWFibGUtYmluZGluZ3MgCiAgICAgKi8KICAgIERFQlVHRFVNUFNFQ1RJT04oInNlbmQiLCAiVmFyQmluZExpc3QiKTsKICAgIGZvciAodnAgPSBwZHUtPnZhcmlhYmxlczsgdnA7IHZwID0gdnAtPm5leHRfdmFyaWFibGUpIHsKICAgICAgICBERUJVR0RVTVBTRUNUSU9OKCJzZW5kIiwgIlZhckJpbmQiKTsKICAgICAgICBjcCA9IHNubXBfYnVpbGRfdmFyX29wKGNwLCB2cC0+bmFtZSwgJnZwLT5uYW1lX2xlbmd0aCwgdnAtPnR5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2cC0+dmFsX2xlbiwgKHVfY2hhciAqKSB2cC0+dmFsLnN0cmluZywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG91dF9sZW5ndGgpOwogICAgICAgIERFQlVHSU5ERU5UTEVTUygpOwogICAgICAgIGlmIChjcCA9PSBOVUxMKQogICAgICAgICAgICByZXR1cm4gTlVMTDsKICAgIH0KICAgIERFQlVHSU5ERU5UTEVTUygpOwoKICAgIC8qCiAgICAgKiBpbnNlcnQgYWN0dWFsIGxlbmd0aCBvZiB2YXJpYWJsZS1iaW5kaW5ncyBzZXF1ZW5jZSAKICAgICAqLwogICAgYXNuX2J1aWxkX3NlcXVlbmNlKGgyLCAmbGVuZ3RoLAogICAgICAgICAgICAgICAgICAgICAgICh1X2NoYXIpIChBU05fU0VRVUVOQ0UgfCBBU05fQ09OU1RSVUNUT1IpLAogICAgICAgICAgICAgICAgICAgICAgIGNwIC0gaDJlKTsKCiAgICAvKgogICAgICogaW5zZXJ0IGFjdHVhbCBsZW5ndGggb2YgUERVIHNlcXVlbmNlIAogICAgICovCiAgICBhc25fYnVpbGRfc2VxdWVuY2UoaDEsICZsZW5ndGgsICh1X2NoYXIpIHBkdS0+Y29tbWFuZCwgY3AgLSBoMWUpOwoKICAgIHJldHVybiBjcDsKfQoKI2lmZGVmIE5FVFNOTVBfVVNFX1JFVkVSU0VfQVNORU5DT0RJTkcKLyoKICogT24gZXJyb3IsIHJldHVybnMgMCAobGlrZWx5IGFuIGVuY29kaW5nIHByb2JsZW0pLiAgCiAqLwppbnQKc25tcF9wZHVfcmVhbGxvY19yYnVpbGQodV9jaGFyICoqIHBrdCwgc2l6ZV90ICogcGt0X2xlbiwgc2l6ZV90ICogb2Zmc2V0LAogICAgICAgICAgICAgICAgICAgICAgICBuZXRzbm1wX3BkdSAqcGR1KQp7CiNpZm5kZWYgVlBDQUNIRV9TSVpFCiNkZWZpbmUgVlBDQUNIRV9TSVpFIDUwCiNlbmRpZgogICAgbmV0c25tcF92YXJpYWJsZV9saXN0ICp2cGNhY2hlW1ZQQ0FDSEVfU0laRV07CiAgICBuZXRzbm1wX3ZhcmlhYmxlX2xpc3QgKnZwLCAqdG1wdnA7CiAgICBzaXplX3QgICAgICAgICAgc3RhcnRfb2Zmc2V0ID0gKm9mZnNldDsKICAgIGludCAgICAgICAgICAgICBpLCB3cmFwcGVkID0gMCwgbm90ZG9uZSwgZmluYWwsIHJjID0gMDsKCiAgICBERUJVR01TR1RMKCgic25tcF9wZHVfcmVhbGxvY19yYnVpbGQiLCAic3RhcnRpbmdcbiIpKTsKICAgIGZvciAodnAgPSBwZHUtPnZhcmlhYmxlcywgaSA9IFZQQ0FDSEVfU0laRSAtIDE7IHZwOwogICAgICAgICB2cCA9IHZwLT5uZXh0X3ZhcmlhYmxlLCBpLS0pIHsKICAgICAgICBpZiAoaSA8IDApIHsKICAgICAgICAgICAgd3JhcHBlZCA9IG5vdGRvbmUgPSAxOwogICAgICAgICAgICBpID0gVlBDQUNIRV9TSVpFIC0gMTsKICAgICAgICAgICAgREVCVUdNU0dUTCgoInNubXBfcGR1X3JlYWxsb2NfcmJ1aWxkIiwgIndyYXBwZWRcbiIpKTsKICAgICAgICB9CiAgICAgICAgdnBjYWNoZVtpXSA9IHZwOwogICAgfQogICAgZmluYWwgPSBpICsgMTsKCiAgICBkbyB7CiAgICAgICAgZm9yIChpID0gZmluYWw7IGkgPCBWUENBQ0hFX1NJWkU7IGkrKykgewogICAgICAgICAgICB2cCA9IHZwY2FjaGVbaV07CiAgICAgICAgICAgIERFQlVHRFVNUFNFQ1RJT04oInNlbmQiLCAiVmFyQmluZCIpOwogICAgICAgICAgICByYyA9IHNubXBfcmVhbGxvY19yYnVpbGRfdmFyX29wKHBrdCwgcGt0X2xlbiwgb2Zmc2V0LCAxLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZwLT5uYW1lLCAmdnAtPm5hbWVfbGVuZ3RoLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZwLT50eXBlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICh1X2NoYXIgKikgdnAtPnZhbC5zdHJpbmcsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdnAtPnZhbF9sZW4pOwogICAgICAgICAgICBERUJVR0lOREVOVExFU1MoKTsKICAgICAgICAgICAgaWYgKHJjID09IDApIHsKICAgICAgICAgICAgICAgIHJldHVybiAwOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBERUJVR0lOREVOVExFU1MoKTsKICAgICAgICBpZiAod3JhcHBlZCkgewogICAgICAgICAgICBub3Rkb25lID0gMTsKICAgICAgICAgICAgZm9yIChpID0gMDsgaSA8IGZpbmFsOyBpKyspIHsKICAgICAgICAgICAgICAgIHZwID0gdnBjYWNoZVtpXTsKICAgICAgICAgICAgICAgIERFQlVHRFVNUFNFQ1RJT04oInNlbmQiLCAiVmFyQmluZCIpOwogICAgICAgICAgICAgICAgcmMgPSBzbm1wX3JlYWxsb2NfcmJ1aWxkX3Zhcl9vcChwa3QsIHBrdF9sZW4sIG9mZnNldCwgMSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdnAtPm5hbWUsICZ2cC0+bmFtZV9sZW5ndGgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZwLT50eXBlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAodV9jaGFyICopIHZwLT52YWwuc3RyaW5nLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2cC0+dmFsX2xlbik7CiAgICAgICAgICAgICAgICBERUJVR0lOREVOVExFU1MoKTsKICAgICAgICAgICAgICAgIGlmIChyYyA9PSAwKSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIDA7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmIChmaW5hbCA9PSAwKSB7CiAgICAgICAgICAgICAgICB0bXB2cCA9IHZwY2FjaGVbVlBDQUNIRV9TSVpFIC0gMV07CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICB0bXB2cCA9IHZwY2FjaGVbZmluYWwgLSAxXTsKICAgICAgICAgICAgfQogICAgICAgICAgICB3cmFwcGVkID0gMDsKCiAgICAgICAgICAgIGZvciAodnAgPSBwZHUtPnZhcmlhYmxlcywgaSA9IFZQQ0FDSEVfU0laRSAtIDE7CiAgICAgICAgICAgICAgICAgdnAgJiYgdnAgIT0gdG1wdnA7IHZwID0gdnAtPm5leHRfdmFyaWFibGUsIGktLSkgewogICAgICAgICAgICAgICAgaWYgKGkgPCAwKSB7CiAgICAgICAgICAgICAgICAgICAgd3JhcHBlZCA9IDE7CiAgICAgICAgICAgICAgICAgICAgaSA9IFZQQ0FDSEVfU0laRSAtIDE7CiAgICAgICAgICAgICAgICAgICAgREVCVUdNU0dUTCgoInNubXBfcGR1X3JlYWxsb2NfcmJ1aWxkIiwgIndyYXBwZWRcbiIpKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHZwY2FjaGVbaV0gPSB2cDsKICAgICAgICAgICAgfQogICAgICAgICAgICBmaW5hbCA9IGkgKyAxOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIG5vdGRvbmUgPSAwOwogICAgICAgIH0KICAgIH0gd2hpbGUgKG5vdGRvbmUpOwoKICAgIC8qCiAgICAgKiBTYXZlIGN1cnJlbnQgbG9jYXRpb24gYW5kIGJ1aWxkIFNFUVVFTkNFIHRhZyBhbmQgbGVuZ3RoIHBsYWNlaG9sZGVyIGZvcgogICAgICogdmFyaWFibGUtYmluZGluZ3Mgc2VxdWVuY2UgKGFjdHVhbCBsZW5ndGggd2lsbCBiZSBpbnNlcnRlZCBsYXRlcikuICAKICAgICAqLwoKICAgIHJjID0gYXNuX3JlYWxsb2NfcmJ1aWxkX3NlcXVlbmNlKHBrdCwgcGt0X2xlbiwgb2Zmc2V0LCAxLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKHVfY2hhcikgKEFTTl9TRVFVRU5DRSB8CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQVNOX0NPTlNUUlVDVE9SKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICpvZmZzZXQgLSBzdGFydF9vZmZzZXQpOwoKICAgIC8qCiAgICAgKiBTdG9yZSBmaWVsZHMgaW4gdGhlIFBEVSBwcmVjZWVkaW5nIHRoZSB2YXJpYWJsZS1iaW5kaW5ncyBzZXF1ZW5jZS4gIAogICAgICovCiAgICBpZiAocGR1LT5jb21tYW5kICE9IFNOTVBfTVNHX1RSQVApIHsKICAgICAgICAvKgogICAgICAgICAqIEVycm9yIGluZGV4IChnZXRidWxrIG1heC1yZXBldGl0aW9ucykuICAKICAgICAgICAgKi8KICAgICAgICBERUJVR0RVTVBIRUFERVIoInNlbmQiLCAiZXJyb3IgaW5kZXgiKTsKICAgICAgICByYyA9IGFzbl9yZWFsbG9jX3JidWlsZF9pbnQocGt0LCBwa3RfbGVuLCBvZmZzZXQsIDEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICh1X2NoYXIpIChBU05fVU5JVkVSU0FMIHwgQVNOX1BSSU1JVElWRQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfCBBU05fSU5URUdFUiksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZwZHUtPmVycmluZGV4LCBzaXplb2YocGR1LT5lcnJpbmRleCkpOwogICAgICAgIERFQlVHSU5ERU5UTEVTUygpOwogICAgICAgIGlmIChyYyA9PSAwKSB7CiAgICAgICAgICAgIHJldHVybiAwOwogICAgICAgIH0KCiAgICAgICAgLyoKICAgICAgICAgKiBFcnJvciBzdGF0dXMgKGdldGJ1bGsgbm9uLXJlcGVhdGVycykuICAKICAgICAgICAgKi8KICAgICAgICBERUJVR0RVTVBIRUFERVIoInNlbmQiLCAiZXJyb3Igc3RhdHVzIik7CiAgICAgICAgcmMgPSBhc25fcmVhbGxvY19yYnVpbGRfaW50KHBrdCwgcGt0X2xlbiwgb2Zmc2V0LCAxLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAodV9jaGFyKSAoQVNOX1VOSVZFUlNBTCB8IEFTTl9QUklNSVRJVkUKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgQVNOX0lOVEVHRVIpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmcGR1LT5lcnJzdGF0LCBzaXplb2YocGR1LT5lcnJzdGF0KSk7CiAgICAgICAgREVCVUdJTkRFTlRMRVNTKCk7CiAgICAgICAgaWYgKHJjID09IDApIHsKICAgICAgICAgICAgcmV0dXJuIDA7CiAgICAgICAgfQoKICAgICAgICAvKgogICAgICAgICAqIFJlcXVlc3QgSUQuICAKICAgICAgICAgKi8KICAgICAgICBERUJVR0RVTVBIRUFERVIoInNlbmQiLCAicmVxdWVzdF9pZCIpOwogICAgICAgIHJjID0gYXNuX3JlYWxsb2NfcmJ1aWxkX2ludChwa3QsIHBrdF9sZW4sIG9mZnNldCwgMSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKHVfY2hhcikgKEFTTl9VTklWRVJTQUwgfCBBU05fUFJJTUlUSVZFCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8IEFTTl9JTlRFR0VSKSwgJnBkdS0+cmVxaWQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNpemVvZihwZHUtPnJlcWlkKSk7CiAgICAgICAgREVCVUdJTkRFTlRMRVNTKCk7CiAgICAgICAgaWYgKHJjID09IDApIHsKICAgICAgICAgICAgcmV0dXJuIDA7CiAgICAgICAgfQogICAgfSBlbHNlIHsKICAgICAgICAvKgogICAgICAgICAqIEFuIFNOTVB2MSB0cmFwIFBEVS4gIAogICAgICAgICAqLwoKICAgICAgICAvKgogICAgICAgICAqIFRpbWVzdGFtcC4gIAogICAgICAgICAqLwogICAgICAgIERFQlVHRFVNUEhFQURFUigic2VuZCIsICJ0aW1lc3RhbXAiKTsKICAgICAgICByYyA9IGFzbl9yZWFsbG9jX3JidWlsZF91bnNpZ25lZF9pbnQocGt0LCBwa3RfbGVuLCBvZmZzZXQsIDEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICh1X2NoYXIpIChBU05fVElNRVRJQ0tTIHwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEFTTl9QUklNSVRJVkUpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmcGR1LT50aW1lLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaXplb2YocGR1LT50aW1lKSk7CiAgICAgICAgREVCVUdJTkRFTlRMRVNTKCk7CiAgICAgICAgaWYgKHJjID09IDApIHsKICAgICAgICAgICAgcmV0dXJuIDA7CiAgICAgICAgfQoKICAgICAgICAvKgogICAgICAgICAqIFNwZWNpZmljIHRyYXAuICAKICAgICAgICAgKi8KICAgICAgICBERUJVR0RVTVBIRUFERVIoInNlbmQiLCAic3BlY2lmaWMgdHJhcCBudW1iZXIiKTsKICAgICAgICByYyA9IGFzbl9yZWFsbG9jX3JidWlsZF9pbnQocGt0LCBwa3RfbGVuLCBvZmZzZXQsIDEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICh1X2NoYXIpIChBU05fVU5JVkVSU0FMIHwgQVNOX1BSSU1JVElWRQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfCBBU05fSU5URUdFUiksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChsb25nICopICZwZHUtPnNwZWNpZmljX3R5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNpemVvZihwZHUtPnNwZWNpZmljX3R5cGUpKTsKICAgICAgICBERUJVR0lOREVOVExFU1MoKTsKICAgICAgICBpZiAocmMgPT0gMCkgewogICAgICAgICAgICByZXR1cm4gMDsKICAgICAgICB9CgogICAgICAgIC8qCiAgICAgICAgICogR2VuZXJpYyB0cmFwLiAgCiAgICAgICAgICovCiAgICAgICAgREVCVUdEVU1QSEVBREVSKCJzZW5kIiwgImdlbmVyaWMgdHJhcCBudW1iZXIiKTsKICAgICAgICByYyA9IGFzbl9yZWFsbG9jX3JidWlsZF9pbnQocGt0LCBwa3RfbGVuLCBvZmZzZXQsIDEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICh1X2NoYXIpIChBU05fVU5JVkVSU0FMIHwgQVNOX1BSSU1JVElWRQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfCBBU05fSU5URUdFUiksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChsb25nICopICZwZHUtPnRyYXBfdHlwZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2l6ZW9mKHBkdS0+dHJhcF90eXBlKSk7CiAgICAgICAgREVCVUdJTkRFTlRMRVNTKCk7CiAgICAgICAgaWYgKHJjID09IDApIHsKICAgICAgICAgICAgcmV0dXJuIDA7CiAgICAgICAgfQoKICAgICAgICAvKgogICAgICAgICAqIEFnZW50LWFkZHIuICAKICAgICAgICAgKi8KICAgICAgICBERUJVR0RVTVBIRUFERVIoInNlbmQiLCAiYWdlbnQgQWRkcmVzcyIpOwogICAgICAgIHJjID0gYXNuX3JlYWxsb2NfcmJ1aWxkX3N0cmluZyhwa3QsIHBrdF9sZW4sIG9mZnNldCwgMSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKHVfY2hhcikgKEFTTl9JUEFERFJFU1MgfAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQVNOX1BSSU1JVElWRSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICh1X2NoYXIgKikgcGR1LT5hZ2VudF9hZGRyLCA0KTsKICAgICAgICBERUJVR0lOREVOVExFU1MoKTsKICAgICAgICBpZiAocmMgPT0gMCkgewogICAgICAgICAgICByZXR1cm4gMDsKICAgICAgICB9CgogICAgICAgIC8qCiAgICAgICAgICogRW50ZXJwcmlzZS4gIAogICAgICAgICAqLwogICAgICAgIERFQlVHRFVNUEhFQURFUigic2VuZCIsICJlbnRlcnByaXNlIE9CSklEIik7CiAgICAgICAgcmMgPSBhc25fcmVhbGxvY19yYnVpbGRfb2JqaWQocGt0LCBwa3RfbGVuLCBvZmZzZXQsIDEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKHVfY2hhcikgKEFTTl9VTklWRVJTQUwgfAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBU05fUFJJTUlUSVZFIHwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQVNOX09CSkVDVF9JRCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKG9pZCAqKSBwZHUtPmVudGVycHJpc2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGR1LT5lbnRlcnByaXNlX2xlbmd0aCk7CiAgICAgICAgREVCVUdJTkRFTlRMRVNTKCk7CiAgICAgICAgaWYgKHJjID09IDApIHsKICAgICAgICAgICAgcmV0dXJuIDA7CiAgICAgICAgfQogICAgfQoKICAgIC8qCiAgICAgKiBCdWlsZCB0aGUgUERVIHNlcXVlbmNlLiAgCiAgICAgKi8KICAgIHJjID0gYXNuX3JlYWxsb2NfcmJ1aWxkX3NlcXVlbmNlKHBrdCwgcGt0X2xlbiwgb2Zmc2V0LCAxLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKHVfY2hhcikgcGR1LT5jb21tYW5kLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKm9mZnNldCAtIHN0YXJ0X29mZnNldCk7CiAgICByZXR1cm4gcmM7Cn0KI2VuZGlmICAgICAgICAgICAgICAgICAgICAgICAgICAvKiBORVRTTk1QX1VTRV9SRVZFUlNFX0FTTkVOQ09ESU5HICovCgovKgogKiBQYXJzZXMgdGhlIHBhY2tldCByZWNlaXZlZCB0byBkZXRlcm1pbmUgdmVyc2lvbiwgZWl0aGVyIGRpcmVjdGx5CiAqIGZyb20gcGFja2V0cyB2ZXJzaW9uIGZpZWxkIG9yIGluZmVycmVkIGZyb20gQVNOLjEgY29uc3RydWN0LgogKi8Kc3RhdGljIGludApzbm1wX3BhcnNlX3ZlcnNpb24odV9jaGFyICogZGF0YSwgc2l6ZV90IGxlbmd0aCkKewogICAgdV9jaGFyICAgICAgICAgIHR5cGU7CiAgICBsb25nICAgICAgICAgICAgdmVyc2lvbiA9IFNOTVBFUlJfQkFEX1ZFUlNJT047CgogICAgZGF0YSA9IGFzbl9wYXJzZV9zZXF1ZW5jZShkYXRhLCAmbGVuZ3RoLCAmdHlwZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKEFTTl9TRVFVRU5DRSB8IEFTTl9DT05TVFJVQ1RPUiksICJ2ZXJzaW9uIik7CiAgICBpZiAoZGF0YSkgewogICAgICAgIGRhdGEgPQogICAgICAgICAgICBhc25fcGFyc2VfaW50KGRhdGEsICZsZW5ndGgsICZ0eXBlLCAmdmVyc2lvbiwgc2l6ZW9mKHZlcnNpb24pKTsKICAgICAgICBpZiAoIWRhdGEgfHwgdHlwZSAhPSBBU05fSU5URUdFUikgewogICAgICAgICAgICByZXR1cm4gU05NUEVSUl9CQURfVkVSU0lPTjsKICAgICAgICB9CiAgICB9CiAgICByZXR1cm4gdmVyc2lvbjsKfQoKCmludApzbm1wdjNfcGFyc2UobmV0c25tcF9wZHUgKnBkdSwKICAgICAgICAgICAgIHVfY2hhciAqIGRhdGEsCiAgICAgICAgICAgICBzaXplX3QgKiBsZW5ndGgsCiAgICAgICAgICAgICB1X2NoYXIgKiogYWZ0ZXJfaGVhZGVyLCBuZXRzbm1wX3Nlc3Npb24gKiBzZXNzKQp7CiAgICB1X2NoYXIgICAgICAgICAgdHlwZSwgbXNnX2ZsYWdzOwogICAgbG9uZyAgICAgICAgICAgIHZlciwgbXNnX21heF9zaXplLCBtc2dfc2VjX21vZGVsOwogICAgc2l6ZV90ICAgICAgICAgIG1heF9zaXplX3Jlc3BvbnNlOwogICAgdV9jaGFyICAgICAgICAgIHRtcF9idWZbU05NUF9NQVhfTVNHX1NJWkVdOwogICAgc2l6ZV90ICAgICAgICAgIHRtcF9idWZfbGVuOwogICAgdV9jaGFyICAgICAgICAgIHBkdV9idWZbU05NUF9NQVhfTVNHX1NJWkVdOwogICAgdV9jaGFyICAgICAgICAgKm1hbGxvY2J1ZiA9IE5VTEw7CiAgICBzaXplX3QgICAgICAgICAgcGR1X2J1Zl9sZW4gPSBTTk1QX01BWF9NU0dfU0laRTsKICAgIHVfY2hhciAgICAgICAgICpzZWNfcGFyYW1zOwogICAgdV9jaGFyICAgICAgICAgKm1zZ19kYXRhOwogICAgdV9jaGFyICAgICAgICAgKmNwOwogICAgc2l6ZV90ICAgICAgICAgIGFzbl9sZW4sIG1zZ19sZW47CiAgICBpbnQgICAgICAgICAgICAgcmV0LCByZXRfdmFsOwogICAgc3RydWN0IHNubXBfc2VjbW9kX2RlZiAqc3B0cjsKCgogICAgbXNnX2RhdGEgPSBkYXRhOwogICAgbXNnX2xlbiA9ICpsZW5ndGg7CgoKICAgIC8qCiAgICAgKiBtZXNzYWdlIGlzIGFuIEFTTi4xIFNFUVVFTkNFICAKICAgICAqLwogICAgREVCVUdEVU1QU0VDVElPTigicmVjdiIsICJTTk1QdjMgTWVzc2FnZSIpOwogICAgZGF0YSA9IGFzbl9wYXJzZV9zZXF1ZW5jZShkYXRhLCBsZW5ndGgsICZ0eXBlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoQVNOX1NFUVVFTkNFIHwgQVNOX0NPTlNUUlVDVE9SKSwgIm1lc3NhZ2UiKTsKICAgIGlmIChkYXRhID09IE5VTEwpIHsKICAgICAgICAvKgogICAgICAgICAqIGVycm9yIG1zZyBkZXRhaWwgaXMgc2V0IAogICAgICAgICAqLwogICAgICAgIHNubXBfaW5jcmVtZW50X3N0YXRpc3RpYyhTVEFUX1NOTVBJTkFTTlBBUlNFRVJSUyk7CiAgICAgICAgREVCVUdJTkRFTlRMRVNTKCk7CiAgICAgICAgcmV0dXJuIFNOTVBFUlJfQVNOX1BBUlNFX0VSUjsKICAgIH0KCiAgICAvKgogICAgICogcGFyc2UgbXNnVmVyc2lvbiAgCiAgICAgKi8KICAgIERFQlVHRFVNUEhFQURFUigicmVjdiIsICJTTk1QIFZlcnNpb24gTnVtYmVyIik7CiAgICBkYXRhID0gYXNuX3BhcnNlX2ludChkYXRhLCBsZW5ndGgsICZ0eXBlLCAmdmVyLCBzaXplb2YodmVyKSk7CiAgICBERUJVR0lOREVOVExFU1MoKTsKICAgIGlmIChkYXRhID09IE5VTEwpIHsKICAgICAgICBFUlJPUl9NU0coImJhZCBwYXJzZSBvZiB2ZXJzaW9uIik7CiAgICAgICAgc25tcF9pbmNyZW1lbnRfc3RhdGlzdGljKFNUQVRfU05NUElOQVNOUEFSU0VFUlJTKTsKICAgICAgICBERUJVR0lOREVOVExFU1MoKTsKICAgICAgICByZXR1cm4gU05NUEVSUl9BU05fUEFSU0VfRVJSOwogICAgfQogICAgcGR1LT52ZXJzaW9uID0gdmVyOwoKICAgIC8qCiAgICAgKiBwYXJzZSBtc2dHbG9iYWxEYXRhIHNlcXVlbmNlICAKICAgICAqLwogICAgY3AgPSBkYXRhOwogICAgYXNuX2xlbiA9ICpsZW5ndGg7CiAgICBERUJVR0RVTVBTRUNUSU9OKCJyZWN2IiwgIm1zZ0dsb2JhbERhdGEiKTsKICAgIGRhdGEgPSBhc25fcGFyc2Vfc2VxdWVuY2UoZGF0YSwgJmFzbl9sZW4sICZ0eXBlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoQVNOX1NFUVVFTkNFIHwgQVNOX0NPTlNUUlVDVE9SKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIm1zZ0dsb2JhbERhdGEiKTsKICAgIGlmIChkYXRhID09IE5VTEwpIHsKICAgICAgICAvKgogICAgICAgICAqIGVycm9yIG1zZyBkZXRhaWwgaXMgc2V0IAogICAgICAgICAqLwogICAgICAgIHNubXBfaW5jcmVtZW50X3N0YXRpc3RpYyhTVEFUX1NOTVBJTkFTTlBBUlNFRVJSUyk7CiAgICAgICAgREVCVUdJTkRFTlRBREQoLTQpOwogICAgICAgIHJldHVybiBTTk1QRVJSX0FTTl9QQVJTRV9FUlI7CiAgICB9CiAgICAqbGVuZ3RoIC09IGRhdGEgLSBjcDsgICAgICAgLyogc3VidHJhY3Qgb2ZmIHRoZSBsZW5ndGggb2YgdGhlIGhlYWRlciAqLwoKICAgIC8qCiAgICAgKiBtc2dJRCAKICAgICAqLwogICAgREVCVUdEVU1QSEVBREVSKCJyZWN2IiwgIm1zZ0lEIik7CiAgICBkYXRhID0KICAgICAgICBhc25fcGFyc2VfaW50KGRhdGEsIGxlbmd0aCwgJnR5cGUsICZwZHUtPm1zZ2lkLAogICAgICAgICAgICAgICAgICAgICAgc2l6ZW9mKHBkdS0+bXNnaWQpKTsKICAgIERFQlVHSU5ERU5UTEVTUygpOwogICAgaWYgKGRhdGEgPT0gTlVMTCB8fCB0eXBlICE9IEFTTl9JTlRFR0VSKSB7CiAgICAgICAgRVJST1JfTVNHKCJlcnJvciBwYXJzaW5nIG1zZ0lEIik7CiAgICAgICAgREVCVUdJTkRFTlRBREQoLTQpOwogICAgICAgIHNubXBfaW5jcmVtZW50X3N0YXRpc3RpYyhTVEFUX1NOTVBJTkFTTlBBUlNFRVJSUyk7CiAgICAgICAgcmV0dXJuIFNOTVBFUlJfQVNOX1BBUlNFX0VSUjsKICAgIH0KCiAgICAvKgogICAgICogQ2hlY2sgdGhlIG1zZ0lEIHdlIHJlY2VpdmVkIGlzIGEgbGVnYWwgdmFsdWUuICBJZiBub3QsIHRoZW4gaW5jcmVtZW50CiAgICAgKiBzbm1wSW5BU05QYXJzZUVycnMgYW5kIHJldHVybiB0aGUgYXBwcm9wcmlhdGUgZXJyb3IgKHNlZSBSRkMgMjU3MiwKICAgICAqIHBhcmEuIDcuMiwgc2VjdGlvbiAyIC0tIG5vdGUgdGhhdCBhIGJhZCBtc2dJRCBtZWFucyB0aGF0IHRoZSByZWNlaXZlZAogICAgICogbWVzc2FnZSBpcyBOT1QgYSBzZXJpYWxpaXphdGlvbiBvZiBhbiBTTk1QdjNNZXNzYWdlLCBzaW5jZSB0aGUgbXNnSUQKICAgICAqIGZpZWxkIGlzIG91dCBvZiBib3VuZHMpLiAgCiAgICAgKi8KCiAgICBpZiAocGR1LT5tc2dpZCA8IDAgfHwgcGR1LT5tc2dpZCA+IDB4N2ZmZmZmZmYpIHsKICAgICAgICBzbm1wX2xvZyhMT0dfRVJSLCAiUmVjZWl2ZWQgYmFkIG1zZ0lEICglbGQgJXMgJXMpLlxuIiwgcGR1LT5tc2dpZCwKICAgICAgICAgICAgICAgICAocGR1LT5tc2dpZCA8IDApID8gIjwiIDogIj4iLAogICAgICAgICAgICAgICAgIChwZHUtPm1zZ2lkIDwgMCkgPyAiMCIgOiAiMl4zMSAtIDEiKTsKICAgICAgICBzbm1wX2luY3JlbWVudF9zdGF0aXN0aWMoU1RBVF9TTk1QSU5BU05QQVJTRUVSUlMpOwogICAgICAgIERFQlVHSU5ERU5UQUREKC00KTsKICAgICAgICByZXR1cm4gU05NUEVSUl9BU05fUEFSU0VfRVJSOwogICAgfQoKICAgIC8qCiAgICAgKiBtc2dNYXhTaXplIAogICAgICovCiAgICBERUJVR0RVTVBIRUFERVIoInJlY3YiLCAibXNnTWF4U2l6ZSIpOwogICAgZGF0YSA9IGFzbl9wYXJzZV9pbnQoZGF0YSwgbGVuZ3RoLCAmdHlwZSwgJm1zZ19tYXhfc2l6ZSwKICAgICAgICAgICAgICAgICAgICAgICAgIHNpemVvZihtc2dfbWF4X3NpemUpKTsKICAgIERFQlVHSU5ERU5UTEVTUygpOwogICAgaWYgKGRhdGEgPT0gTlVMTCB8fCB0eXBlICE9IEFTTl9JTlRFR0VSKSB7CiAgICAgICAgRVJST1JfTVNHKCJlcnJvciBwYXJzaW5nIG1zZ01heFNpemUiKTsKICAgICAgICBzbm1wX2luY3JlbWVudF9zdGF0aXN0aWMoU1RBVF9TTk1QSU5BU05QQVJTRUVSUlMpOwogICAgICAgIERFQlVHSU5ERU5UQUREKC00KTsKICAgICAgICByZXR1cm4gU05NUEVSUl9BU05fUEFSU0VfRVJSOwogICAgfQoKICAgIC8qCiAgICAgKiBDaGVjayB0aGUgbXNnTWF4U2l6ZSB3ZSByZWNlaXZlZCBpcyBhIGxlZ2FsIHZhbHVlLiAgSWYgbm90LCB0aGVuCiAgICAgKiBpbmNyZW1lbnQgc25tcEluQVNOUGFyc2VFcnJzIGFuZCByZXR1cm4gdGhlIGFwcHJvcHJpYXRlIGVycm9yIChzZWUgUkZDCiAgICAgKiAyNTcyLCBwYXJhLiA3LjIsIHNlY3Rpb24gMiAtLSBub3RlIHRoYXQgYSBiYWQgbXNnTWF4U2l6ZSBtZWFucyB0aGF0IHRoZQogICAgICogcmVjZWl2ZWQgbWVzc2FnZSBpcyBOT1QgYSBzZXJpYWxpaXphdGlvbiBvZiBhbiBTTk1QdjNNZXNzYWdlLCBzaW5jZSB0aGUKICAgICAqIG1zZ01heFNpemUgZmllbGQgaXMgb3V0IG9mIGJvdW5kcykuCiAgICAgKiAKICAgICAqIE5vdGUgd2Ugc3RvcmUgdGhlIG1zZ01heFNpemUgb24gYSBwZXItc2Vzc2lvbiBiYXNpcyB3aGljaCBhbHNvIHNlZW1zCiAgICAgKiByZWFzb25hYmxlOyBpdCBjb3VsZCB2YXJ5IGZyb20gUERVIHRvIFBEVSBidXQgdGhhdCB3b3VsZCBiZSBzdHJhbmdlCiAgICAgKiAoYWxzbyBzaW5jZSB3ZSBkZWFsIHdpdGggYSBQRFUgYXQgYSB0aW1lLCBpdCB3b3VsZG4ndCBtYWtlIGFueQogICAgICogZGlmZmVyZW5jZSB0byBvdXIgcmVzcG9uc2VzLCBpZiBhbnkpLiAgCiAgICAgKi8KCiAgICBpZiAobXNnX21heF9zaXplIDwgNDg0KSB7CiAgICAgICAgc25tcF9sb2coTE9HX0VSUiwgIlJlY2VpdmVkIGJhZCBtc2dNYXhTaXplICglbHUgPCA0ODQpLlxuIiwKICAgICAgICAgICAgICAgICBtc2dfbWF4X3NpemUpOwogICAgICAgIHNubXBfaW5jcmVtZW50X3N0YXRpc3RpYyhTVEFUX1NOTVBJTkFTTlBBUlNFRVJSUyk7CiAgICAgICAgREVCVUdJTkRFTlRBREQoLTQpOwogICAgICAgIHJldHVybiBTTk1QRVJSX0FTTl9QQVJTRV9FUlI7CiAgICB9IGVsc2UgaWYgKG1zZ19tYXhfc2l6ZSA+IDB4N2ZmZmZmZmYpIHsKICAgICAgICBzbm1wX2xvZyhMT0dfRVJSLCAiUmVjZWl2ZWQgYmFkIG1zZ01heFNpemUgKCVsdSA+IDJeMzEgLSAxKS5cbiIsCiAgICAgICAgICAgICAgICAgbXNnX21heF9zaXplKTsKICAgICAgICBzbm1wX2luY3JlbWVudF9zdGF0aXN0aWMoU1RBVF9TTk1QSU5BU05QQVJTRUVSUlMpOwogICAgICAgIERFQlVHSU5ERU5UQUREKC00KTsKICAgICAgICByZXR1cm4gU05NUEVSUl9BU05fUEFSU0VfRVJSOwogICAgfSBlbHNlIHsKICAgICAgICBERUJVR01TR1RMKCgic25tcHYzX3BhcnNlIiwgIm1zZ01heFNpemUgJWx1IHJlY2VpdmVkXG4iLAogICAgICAgICAgICAgICAgICAgIG1zZ19tYXhfc2l6ZSkpOwogICAgICAgIHNlc3MtPnNuZE1zZ01heFNpemUgPSBtc2dfbWF4X3NpemU7CiAgICB9CgogICAgLyoKICAgICAqIG1zZ0ZsYWdzIAogICAgICovCiAgICB0bXBfYnVmX2xlbiA9IFNOTVBfTUFYX01TR19TSVpFOwogICAgREVCVUdEVU1QSEVBREVSKCJyZWN2IiwgIm1zZ0ZsYWdzIik7CiAgICBkYXRhID0gYXNuX3BhcnNlX3N0cmluZyhkYXRhLCBsZW5ndGgsICZ0eXBlLCB0bXBfYnVmLCAmdG1wX2J1Zl9sZW4pOwogICAgREVCVUdJTkRFTlRMRVNTKCk7CiAgICBpZiAoZGF0YSA9PSBOVUxMIHx8IHR5cGUgIT0gQVNOX09DVEVUX1NUUiB8fCB0bXBfYnVmX2xlbiAhPSAxKSB7CiAgICAgICAgRVJST1JfTVNHKCJlcnJvciBwYXJzaW5nIG1zZ0ZsYWdzIik7CiAgICAgICAgc25tcF9pbmNyZW1lbnRfc3RhdGlzdGljKFNUQVRfU05NUElOQVNOUEFSU0VFUlJTKTsKICAgICAgICBERUJVR0lOREVOVEFERCgtNCk7CiAgICAgICAgcmV0dXJuIFNOTVBFUlJfQVNOX1BBUlNFX0VSUjsKICAgIH0KICAgIG1zZ19mbGFncyA9ICp0bXBfYnVmOwogICAgaWYgKG1zZ19mbGFncyAmIFNOTVBfTVNHX0ZMQUdfUlBSVF9CSVQpCiAgICAgICAgcGR1LT5mbGFncyB8PSBTTk1QX01TR19GTEFHX1JQUlRfQklUOwogICAgZWxzZQogICAgICAgIHBkdS0+ZmxhZ3MgJj0gKH5TTk1QX01TR19GTEFHX1JQUlRfQklUKTsKCiAgICAvKgogICAgICogbXNnU2VjdXJpdHlNb2RlbCAKICAgICAqLwogICAgREVCVUdEVU1QSEVBREVSKCJyZWN2IiwgIm1zZ1NlY3VyaXR5TW9kZWwiKTsKICAgIGRhdGEgPSBhc25fcGFyc2VfaW50KGRhdGEsIGxlbmd0aCwgJnR5cGUsICZtc2dfc2VjX21vZGVsLAogICAgICAgICAgICAgICAgICAgICAgICAgc2l6ZW9mKG1zZ19zZWNfbW9kZWwpKTsKICAgIERFQlVHSU5ERU5UQUREKC00KTsgICAgICAgICAvKiByZXR1cm4gZnJvbSBnbG9iYWwgZGF0YSBpbmRlbnQgKi8KICAgIGlmIChkYXRhID09IE5VTEwgfHwgdHlwZSAhPSBBU05fSU5URUdFUiB8fAogICAgICAgIG1zZ19zZWNfbW9kZWwgPCAxIHx8IG1zZ19zZWNfbW9kZWwgPiAweDdmZmZmZmZmKSB7CiAgICAgICAgRVJST1JfTVNHKCJlcnJvciBwYXJzaW5nIG1zZ1NlY3VyaXR5TW9kZWwiKTsKICAgICAgICBzbm1wX2luY3JlbWVudF9zdGF0aXN0aWMoU1RBVF9TTk1QSU5BU05QQVJTRUVSUlMpOwogICAgICAgIERFQlVHSU5ERU5UTEVTUygpOwogICAgICAgIHJldHVybiBTTk1QRVJSX0FTTl9QQVJTRV9FUlI7CiAgICB9CiAgICBzcHRyID0gZmluZF9zZWNfbW9kKG1zZ19zZWNfbW9kZWwpOwogICAgaWYgKCFzcHRyKSB7CiAgICAgICAgc25tcF9sb2coTE9HX1dBUk5JTkcsICJ1bmtub3duIHNlY3VyaXR5IG1vZGVsOiAlbGRcbiIsCiAgICAgICAgICAgICAgICAgbXNnX3NlY19tb2RlbCk7CiAgICAgICAgc25tcF9pbmNyZW1lbnRfc3RhdGlzdGljKFNUQVRfU05NUFVOS05PV05TRUNVUklUWU1PREVMUyk7CiAgICAgICAgREVCVUdJTkRFTlRMRVNTKCk7CiAgICAgICAgcmV0dXJuIFNOTVBFUlJfVU5LTk9XTl9TRUNfTU9ERUw7CiAgICB9CiAgICBwZHUtPnNlY3VyaXR5TW9kZWwgPSBtc2dfc2VjX21vZGVsOwoKICAgIGlmIChtc2dfZmxhZ3MgJiBTTk1QX01TR19GTEFHX1BSSVZfQklUICYmCiAgICAgICAgIShtc2dfZmxhZ3MgJiBTTk1QX01TR19GTEFHX0FVVEhfQklUKSkgewogICAgICAgIEVSUk9SX01TRygiaW52YWxpZCBtZXNzYWdlLCBpbGxlZ2FsIG1zZ0ZsYWdzIik7CiAgICAgICAgc25tcF9pbmNyZW1lbnRfc3RhdGlzdGljKFNUQVRfU05NUElOVkFMSURNU0dTKTsKICAgICAgICBERUJVR0lOREVOVExFU1MoKTsKICAgICAgICByZXR1cm4gU05NUEVSUl9JTlZBTElEX01TRzsKICAgIH0KICAgIHBkdS0+c2VjdXJpdHlMZXZlbCA9ICgobXNnX2ZsYWdzICYgU05NUF9NU0dfRkxBR19BVVRIX0JJVCkKICAgICAgICAgICAgICAgICAgICAgICAgICA/ICgobXNnX2ZsYWdzICYgU05NUF9NU0dfRkxBR19QUklWX0JJVCkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICA/IFNOTVBfU0VDX0xFVkVMX0FVVEhQUklWCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgOiBTTk1QX1NFQ19MRVZFTF9BVVRITk9QUklWKQogICAgICAgICAgICAgICAgICAgICAgICAgIDogU05NUF9TRUNfTEVWRUxfTk9BVVRIKTsKICAgIC8qCiAgICAgKiBlbmQgb2YgbXNnR2xvYmFsRGF0YSAKICAgICAqLwoKICAgIC8qCiAgICAgKiBzZWN1cnRpdHlQYXJhbWV0ZXJzIE9DVEVUIFNUUklORyBiZWdpbnMgYWZ0ZXIgbXNnR2xvYmFsRGF0YSAKICAgICAqLwogICAgc2VjX3BhcmFtcyA9IGRhdGE7CiAgICBwZHUtPmNvbnRleHRFbmdpbmVJRCA9ICh1X2NoYXIgKikgY2FsbG9jKDEsIFNOTVBfTUFYX0VOR19TSVpFKTsKICAgIHBkdS0+Y29udGV4dEVuZ2luZUlETGVuID0gU05NUF9NQVhfRU5HX1NJWkU7CgogICAgLyoKICAgICAqIE5vdGU6IHRoZXJlIGlzIG5vIGxlbmd0aCBsaW1pdCBvbiB0aGUgbXNnQXV0aG9yaXRhdGl2ZUVuZ2luZUlEIGZpZWxkLAogICAgICogYWx0aG91Z2ggd2Ugd291bGQgRVhQRUNUIGl0IHRvIGJlIGxpbWl0ZWQgdG8gMzIgKHRoZSBTbm1wRW5naW5lSUQgVEMKICAgICAqIGxpbWl0KS4gIFdlJ2xsIHVzZSBkb3VibGUgdGhhdCBoZXJlIHRvIGJlIG9uIHRoZSBzYWZlIHNpZGUuICAKICAgICAqLwoKICAgIHBkdS0+c2VjdXJpdHlFbmdpbmVJRCA9ICh1X2NoYXIgKikgY2FsbG9jKDEsIFNOTVBfTUFYX0VOR19TSVpFICogMik7CiAgICBwZHUtPnNlY3VyaXR5RW5naW5lSURMZW4gPSBTTk1QX01BWF9FTkdfU0laRSAqIDI7CiAgICBwZHUtPnNlY3VyaXR5TmFtZSA9IChjaGFyICopIGNhbGxvYygxLCBTTk1QX01BWF9TRUNfTkFNRV9TSVpFKTsKICAgIHBkdS0+c2VjdXJpdHlOYW1lTGVuID0gU05NUF9NQVhfU0VDX05BTUVfU0laRTsKCiAgICBpZiAoKHBkdS0+c2VjdXJpdHlOYW1lID09IE5VTEwpIHx8CiAgICAgICAgKHBkdS0+c2VjdXJpdHlFbmdpbmVJRCA9PSBOVUxMKSB8fAogICAgICAgIChwZHUtPmNvbnRleHRFbmdpbmVJRCA9PSBOVUxMKSkgewogICAgICAgIHJldHVybiBTTk1QRVJSX01BTExPQzsKICAgIH0KCiAgICBpZiAocGR1X2J1Zl9sZW4gPCBtc2dfbGVuCiAgICAgICAgJiYgcGR1LT5zZWN1cml0eUxldmVsID09IFNOTVBfU0VDX0xFVkVMX0FVVEhQUklWKSB7CiAgICAgICAgLyoKICAgICAgICAgKiBzcGFjZSBuZWVkZWQgaXMgbGFyZ2VyIHRoYW4gd2UgaGF2ZSBpbiB0aGUgZGVmYXVsdCBidWZmZXIgCiAgICAgICAgICovCiAgICAgICAgbWFsbG9jYnVmID0gKHVfY2hhciAqKSBjYWxsb2MoMSwgbXNnX2xlbik7CiAgICAgICAgcGR1X2J1Zl9sZW4gPSBtc2dfbGVuOwogICAgICAgIGNwID0gbWFsbG9jYnVmOwogICAgfSBlbHNlIHsKICAgICAgICBtZW1zZXQocGR1X2J1ZiwgMCwgcGR1X2J1Zl9sZW4pOwogICAgICAgIGNwID0gcGR1X2J1ZjsKICAgIH0KCiAgICBERUJVR0RVTVBTRUNUSU9OKCJyZWN2IiwgIlNNIG1zZ1NlY3VyaXR5UGFyYW1ldGVycyIpOwogICAgaWYgKHNwdHItPmRlY29kZSkgewogICAgICAgIHN0cnVjdCBzbm1wX3NlY21vZF9pbmNvbWluZ19wYXJhbXMgcGFybXM7CiAgICAgICAgcGFybXMubXNnUHJvY01vZGVsID0gcGR1LT5tc2dQYXJzZU1vZGVsOwogICAgICAgIHBhcm1zLm1heE1zZ1NpemUgPSBtc2dfbWF4X3NpemU7CiAgICAgICAgcGFybXMuc2VjUGFyYW1zID0gc2VjX3BhcmFtczsKICAgICAgICBwYXJtcy5zZWNNb2RlbCA9IG1zZ19zZWNfbW9kZWw7CiAgICAgICAgcGFybXMuc2VjTGV2ZWwgPSBwZHUtPnNlY3VyaXR5TGV2ZWw7CiAgICAgICAgcGFybXMud2hvbGVNc2cgPSBtc2dfZGF0YTsKICAgICAgICBwYXJtcy53aG9sZU1zZ0xlbiA9IG1zZ19sZW47CiAgICAgICAgcGFybXMuc2VjRW5naW5lSUQgPSBwZHUtPnNlY3VyaXR5RW5naW5lSUQ7CiAgICAgICAgcGFybXMuc2VjRW5naW5lSURMZW4gPSAmcGR1LT5zZWN1cml0eUVuZ2luZUlETGVuOwogICAgICAgIHBhcm1zLnNlY05hbWUgPSBwZHUtPnNlY3VyaXR5TmFtZTsKICAgICAgICBwYXJtcy5zZWNOYW1lTGVuID0gJnBkdS0+c2VjdXJpdHlOYW1lTGVuOwogICAgICAgIHBhcm1zLnNjb3BlZFBkdSA9ICZjcDsKICAgICAgICBwYXJtcy5zY29wZWRQZHVMZW4gPSAmcGR1X2J1Zl9sZW47CiAgICAgICAgcGFybXMubWF4U2l6ZVJlc3BvbnNlID0gJm1heF9zaXplX3Jlc3BvbnNlOwogICAgICAgIHBhcm1zLnNlY1N0YXRlUmVmID0gJnBkdS0+c2VjdXJpdHlTdGF0ZVJlZjsKICAgICAgICBwYXJtcy5zZXNzID0gc2VzczsKICAgICAgICBwYXJtcy5wZHUgPSBwZHU7CiAgICAgICAgcGFybXMubXNnX2ZsYWdzID0gbXNnX2ZsYWdzOwogICAgICAgIHJldF92YWwgPSAoKnNwdHItPmRlY29kZSkgKCZwYXJtcyk7CiAgICB9IGVsc2UgewogICAgICAgIFNOTVBfRlJFRShtYWxsb2NidWYpOwogICAgICAgIERFQlVHSU5ERU5UTEVTUygpOwogICAgICAgIHNubXBfbG9nKExPR19XQVJOSU5HLCAic2VjdXJpdHkgc2VydmljZSAlbGQgY2FuJ3QgZGVjb2RlIHBhY2tldHNcbiIsCiAgICAgICAgICAgICAgICAgbXNnX3NlY19tb2RlbCk7CiAgICAgICAgcmV0dXJuICgtMSk7CiAgICB9CgogICAgaWYgKHJldF92YWwgIT0gU05NUEVSUl9TVUNDRVNTKSB7CiAgICAgICAgREVCVUdEVU1QU0VDVElPTigicmVjdiIsICJTY29wZWRQRFUiKTsKICAgICAgICAvKgogICAgICAgICAqIFBhcnNlIGFzIG11Y2ggYXMgcG9zc2libGUgLS0gdGhvdWdoIEkgZG9uJ3Qgc2VlIHRoZSBwb2ludD8gW2picG5dLiAgCiAgICAgICAgICovCiAgICAgICAgaWYgKGNwKSB7CiAgICAgICAgICAgIGNwID0gc25tcHYzX3Njb3BlZFBEVV9wYXJzZShwZHUsIGNwLCAmcGR1X2J1Zl9sZW4pOwogICAgICAgIH0KICAgICAgICBpZiAoY3ApIHsKICAgICAgICAgICAgREVCVUdQUklOVFBEVVRZUEUoInJlY3YiLCAqY3ApOwogICAgICAgICAgICBzbm1wX3BkdV9wYXJzZShwZHUsIGNwLCAmcGR1X2J1Zl9sZW4pOwogICAgICAgICAgICBERUJVR0lOREVOVEFERCgtOCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgREVCVUdJTkRFTlRBREQoLTQpOwogICAgICAgIH0KCiAgICAgICAgaWYgKG1hbGxvY2J1ZikgewogICAgICAgICAgICBTTk1QX0ZSRUUobWFsbG9jYnVmKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHJldF92YWw7CiAgICB9CgogICAgLyoKICAgICAqIHBhcnNlIHBsYWludGV4dCBTY29wZWRQRFUgc2VxdWVuY2UgCiAgICAgKi8KICAgICpsZW5ndGggPSBwZHVfYnVmX2xlbjsKICAgIERFQlVHRFVNUFNFQ1RJT04oInJlY3YiLCAiU2NvcGVkUERVIik7CiAgICBkYXRhID0gc25tcHYzX3Njb3BlZFBEVV9wYXJzZShwZHUsIGNwLCBsZW5ndGgpOwogICAgaWYgKGRhdGEgPT0gTlVMTCkgewogICAgICAgIHNubXBfaW5jcmVtZW50X3N0YXRpc3RpYyhTVEFUX1NOTVBJTkFTTlBBUlNFRVJSUyk7CiAgICAgICAgREVCVUdJTkRFTlRBREQoLTQpOwogICAgICAgIGlmIChtYWxsb2NidWYpIHsKICAgICAgICAgICAgU05NUF9GUkVFKG1hbGxvY2J1Zik7CiAgICAgICAgfQogICAgICAgIHJldHVybiBTTk1QRVJSX0FTTl9QQVJTRV9FUlI7CiAgICB9CgogICAgLyoKICAgICAqIHBhcnNlIHRoZSBQRFUuICAKICAgICAqLwogICAgaWYgKGFmdGVyX2hlYWRlciAhPSBOVUxMKSB7CiAgICAgICAgKmFmdGVyX2hlYWRlciA9IGRhdGE7CiAgICAgICAgdG1wX2J1Zl9sZW4gPSAqbGVuZ3RoOwogICAgfQoKICAgIERFQlVHUFJJTlRQRFVUWVBFKCJyZWN2IiwgKmRhdGEpOwogICAgcmV0ID0gc25tcF9wZHVfcGFyc2UocGR1LCBkYXRhLCBsZW5ndGgpOwogICAgREVCVUdJTkRFTlRBREQoLTgpOwoKICAgIGlmIChhZnRlcl9oZWFkZXIgIT0gTlVMTCkgewogICAgICAgICpsZW5ndGggPSB0bXBfYnVmX2xlbjsKICAgIH0KCiAgICBpZiAocmV0ICE9IFNOTVBFUlJfU1VDQ0VTUykgewogICAgICAgIEVSUk9SX01TRygiZXJyb3IgcGFyc2luZyBQRFUiKTsKICAgICAgICBzbm1wX2luY3JlbWVudF9zdGF0aXN0aWMoU1RBVF9TTk1QSU5BU05QQVJTRUVSUlMpOwogICAgICAgIGlmIChtYWxsb2NidWYpIHsKICAgICAgICAgICAgU05NUF9GUkVFKG1hbGxvY2J1Zik7CiAgICAgICAgfQogICAgICAgIHJldHVybiBTTk1QRVJSX0FTTl9QQVJTRV9FUlI7CiAgICB9CgogICAgaWYgKG1hbGxvY2J1ZikgewogICAgICAgIFNOTVBfRlJFRShtYWxsb2NidWYpOwogICAgfQogICAgcmV0dXJuIFNOTVBFUlJfU1VDQ0VTUzsKfSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiBlbmQgc25tcHYzX3BhcnNlKCkgKi8KCiNkZWZpbmUgRVJST1JfU1RBVF9MRU5HVEggMTEKCmludApzbm1wdjNfbWFrZV9yZXBvcnQobmV0c25tcF9wZHUgKnBkdSwgaW50IGVycm9yKQp7CgogICAgbG9uZyAgICAgICAgICAgIGx0bXA7CiAgICBzdGF0aWMgb2lkICAgICAgdW5rbm93blNlY3VyaXR5TGV2ZWxbXSA9CiAgICAgICAgeyAxLCAzLCA2LCAxLCA2LCAzLCAxNSwgMSwgMSwgMSwgMCB9OwogICAgc3RhdGljIG9pZCAgICAgIG5vdEluVGltZVdpbmRvd1tdID0KICAgICAgICB7IDEsIDMsIDYsIDEsIDYsIDMsIDE1LCAxLCAxLCAyLCAwIH07CiAgICBzdGF0aWMgb2lkICAgICAgdW5rbm93blVzZXJOYW1lW10gPQogICAgICAgIHsgMSwgMywgNiwgMSwgNiwgMywgMTUsIDEsIDEsIDMsIDAgfTsKICAgIHN0YXRpYyBvaWQgICAgICB1bmtub3duRW5naW5lSURbXSA9CiAgICAgICAgeyAxLCAzLCA2LCAxLCA2LCAzLCAxNSwgMSwgMSwgNCwgMCB9OwogICAgc3RhdGljIG9pZCAgICAgIHdyb25nRGlnZXN0W10gPSB7IDEsIDMsIDYsIDEsIDYsIDMsIDE1LCAxLCAxLCA1LCAwIH07CiAgICBzdGF0aWMgb2lkICAgICAgZGVjcnlwdGlvbkVycm9yW10gPQogICAgICAgIHsgMSwgMywgNiwgMSwgNiwgMywgMTUsIDEsIDEsIDYsIDAgfTsKICAgIG9pZCAgICAgICAgICAgICplcnJfdmFyOwogICAgaW50ICAgICAgICAgICAgIGVycl92YXJfbGVuOwogICAgaW50ICAgICAgICAgICAgIHN0YXRfaW5kOwogICAgc3RydWN0IHNubXBfc2VjbW9kX2RlZiAqc3B0cjsKCiAgICBzd2l0Y2ggKGVycm9yKSB7CiAgICBjYXNlIFNOTVBFUlJfVVNNX1VOS05PV05FTkdJTkVJRDoKICAgICAgICBzdGF0X2luZCA9IFNUQVRfVVNNU1RBVFNVTktOT1dORU5HSU5FSURTOwogICAgICAgIGVycl92YXIgPSB1bmtub3duRW5naW5lSUQ7CiAgICAgICAgZXJyX3Zhcl9sZW4gPSBFUlJPUl9TVEFUX0xFTkdUSDsKICAgICAgICBicmVhazsKICAgIGNhc2UgU05NUEVSUl9VU01fVU5LTk9XTlNFQ1VSSVRZTkFNRToKICAgICAgICBzdGF0X2luZCA9IFNUQVRfVVNNU1RBVFNVTktOT1dOVVNFUk5BTUVTOwogICAgICAgIGVycl92YXIgPSB1bmtub3duVXNlck5hbWU7CiAgICAgICAgZXJyX3Zhcl9sZW4gPSBFUlJPUl9TVEFUX0xFTkdUSDsKICAgICAgICBicmVhazsKICAgIGNhc2UgU05NUEVSUl9VU01fVU5TVVBQT1JURURTRUNVUklUWUxFVkVMOgogICAgICAgIHN0YXRfaW5kID0gU1RBVF9VU01TVEFUU1VOU1VQUE9SVEVEU0VDTEVWRUxTOwogICAgICAgIGVycl92YXIgPSB1bmtub3duU2VjdXJpdHlMZXZlbDsKICAgICAgICBlcnJfdmFyX2xlbiA9IEVSUk9SX1NUQVRfTEVOR1RIOwogICAgICAgIGJyZWFrOwogICAgY2FzZSBTTk1QRVJSX1VTTV9BVVRIRU5USUNBVElPTkZBSUxVUkU6CiAgICAgICAgc3RhdF9pbmQgPSBTVEFUX1VTTVNUQVRTV1JPTkdESUdFU1RTOwogICAgICAgIGVycl92YXIgPSB3cm9uZ0RpZ2VzdDsKICAgICAgICBlcnJfdmFyX2xlbiA9IEVSUk9SX1NUQVRfTEVOR1RIOwogICAgICAgIGJyZWFrOwogICAgY2FzZSBTTk1QRVJSX1VTTV9OT1RJTlRJTUVXSU5ET1c6CiAgICAgICAgc3RhdF9pbmQgPSBTVEFUX1VTTVNUQVRTTk9USU5USU1FV0lORE9XUzsKICAgICAgICBlcnJfdmFyID0gbm90SW5UaW1lV2luZG93OwogICAgICAgIGVycl92YXJfbGVuID0gRVJST1JfU1RBVF9MRU5HVEg7CiAgICAgICAgYnJlYWs7CiAgICBjYXNlIFNOTVBFUlJfVVNNX0RFQ1JZUFRJT05FUlJPUjoKICAgICAgICBzdGF0X2luZCA9IFNUQVRfVVNNU1RBVFNERUNSWVBUSU9ORVJST1JTOwogICAgICAgIGVycl92YXIgPSBkZWNyeXB0aW9uRXJyb3I7CiAgICAgICAgZXJyX3Zhcl9sZW4gPSBFUlJPUl9TVEFUX0xFTkdUSDsKICAgICAgICBicmVhazsKICAgIGRlZmF1bHQ6CiAgICAgICAgcmV0dXJuIFNOTVBFUlJfR0VORVJSOwogICAgfQoKICAgIHNubXBfZnJlZV92YXJiaW5kKHBkdS0+dmFyaWFibGVzKTsgIC8qIGZyZWUgdGhlIGN1cnJlbnQgdmFyYmluZCAqLwoKICAgIHBkdS0+dmFyaWFibGVzID0gTlVMTDsKICAgIFNOTVBfRlJFRShwZHUtPnNlY3VyaXR5RW5naW5lSUQpOwogICAgcGR1LT5zZWN1cml0eUVuZ2luZUlEID0KICAgICAgICBzbm1wdjNfZ2VuZXJhdGVfZW5naW5lSUQoJnBkdS0+c2VjdXJpdHlFbmdpbmVJRExlbik7CiAgICBTTk1QX0ZSRUUocGR1LT5jb250ZXh0RW5naW5lSUQpOwogICAgcGR1LT5jb250ZXh0RW5naW5lSUQgPQogICAgICAgIHNubXB2M19nZW5lcmF0ZV9lbmdpbmVJRCgmcGR1LT5jb250ZXh0RW5naW5lSURMZW4pOwogICAgcGR1LT5jb21tYW5kID0gU05NUF9NU0dfUkVQT1JUOwogICAgcGR1LT5lcnJzdGF0ID0gMDsKICAgIHBkdS0+ZXJyaW5kZXggPSAwOwogICAgU05NUF9GUkVFKHBkdS0+Y29udGV4dE5hbWUpOwogICAgcGR1LT5jb250ZXh0TmFtZSA9IHN0cmR1cCgiIik7CiAgICBwZHUtPmNvbnRleHROYW1lTGVuID0gc3RybGVuKHBkdS0+Y29udGV4dE5hbWUpOwoKICAgIC8qCiAgICAgKiByZXBvcnRzIHNob3VsZG4ndCBjYWNoZSBwcmV2aW91cyBkYXRhLiAKICAgICAqLwogICAgLyoKICAgICAqIEZJWCAtIHllcyB0aGV5IHNob3VsZCBidXQgVVNNIG5lZWRzIHRvIGZvbGxvdyBuZXcgRW9QIHRvIGRldGVybWluZQogICAgICogd2hpY2ggY2FjaGVkIHZhbHVlcyB0byB1c2UgCiAgICAgKi8KICAgIGlmIChwZHUtPnNlY3VyaXR5U3RhdGVSZWYpIHsKICAgICAgICBzcHRyID0gZmluZF9zZWNfbW9kKHBkdS0+c2VjdXJpdHlNb2RlbCk7CiAgICAgICAgaWYgKHNwdHIpIHsKICAgICAgICAgICAgaWYgKHNwdHItPnBkdV9mcmVlX3N0YXRlX3JlZikgewogICAgICAgICAgICAgICAgKCpzcHRyLT5wZHVfZnJlZV9zdGF0ZV9yZWYpIChwZHUtPnNlY3VyaXR5U3RhdGVSZWYpOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgc25tcF9sb2coTE9HX0VSUiwKICAgICAgICAgICAgICAgICAgICAgICAgICJTZWN1cml0eSBNb2RlbCAlZCBjYW4ndCBmcmVlIHN0YXRlIHJlZmVyZW5jZXNcbiIsCiAgICAgICAgICAgICAgICAgICAgICAgICBwZHUtPnNlY3VyaXR5TW9kZWwpOwogICAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgc25tcF9sb2coTE9HX0VSUiwKICAgICAgICAgICAgICAgICAgICAgIkNhbid0IGZpbmQgc2VjdXJpdHkgbW9kZWwgdG8gZnJlZSBwdHI6ICVkXG4iLAogICAgICAgICAgICAgICAgICAgICBwZHUtPnNlY3VyaXR5TW9kZWwpOwogICAgICAgIH0KICAgICAgICBwZHUtPnNlY3VyaXR5U3RhdGVSZWYgPSBOVUxMOwogICAgfQoKICAgIGlmIChlcnJvciA9PSBTTk1QRVJSX1VTTV9OT1RJTlRJTUVXSU5ET1cpIHsKICAgICAgICBwZHUtPnNlY3VyaXR5TGV2ZWwgPSBTTk1QX1NFQ19MRVZFTF9BVVRITk9QUklWOwogICAgfSBlbHNlIHsKICAgICAgICBwZHUtPnNlY3VyaXR5TGV2ZWwgPSBTTk1QX1NFQ19MRVZFTF9OT0FVVEg7CiAgICB9CgogICAgLyoKICAgICAqIGZpbmQgdGhlIGFwcHJvcHJpYXRlIGVycm9yIGNvdW50ZXIgIAogICAgICovCiAgICBsdG1wID0gc25tcF9nZXRfc3RhdGlzdGljKHN0YXRfaW5kKTsKCiAgICAvKgogICAgICogcmV0dXJuIHRoZSBhcHByb3ByaWF0ZSBlcnJvciBjb3VudGVyICAKICAgICAqLwogICAgc25tcF9wZHVfYWRkX3ZhcmlhYmxlKHBkdSwgZXJyX3ZhciwgZXJyX3Zhcl9sZW4sCiAgICAgICAgICAgICAgICAgICAgICAgICAgQVNOX0NPVU5URVIsICh1X2NoYXIgKikgJiBsdG1wLCBzaXplb2YobHRtcCkpOwoKICAgIHJldHVybiBTTk1QRVJSX1NVQ0NFU1M7Cn0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogZW5kIHNubXB2M19tYWtlX3JlcG9ydCgpICovCgoKaW50CnNubXB2M19nZXRfcmVwb3J0X3R5cGUobmV0c25tcF9wZHUgKnBkdSkKewogICAgc3RhdGljIG9pZCAgICAgIHNubXBNUERTdGF0c1tdID0geyAxLCAzLCA2LCAxLCA2LCAzLCAxMSwgMiwgMSB9OwogICAgc3RhdGljIG9pZCAgICAgIHRhcmdldFN0YXRzW10gID0geyAxLCAzLCA2LCAxLCA2LCAzLCAxMiwgMSAgICB9OwogICAgc3RhdGljIG9pZCAgICAgIHVzbVN0YXRzW10gICAgID0geyAxLCAzLCA2LCAxLCA2LCAzLCAxNSwgMSwgMSB9OwogICAgbmV0c25tcF92YXJpYWJsZV9saXN0ICp2cDsKICAgIGludCAgICAgICAgICAgICBycHRfdHlwZSA9IFNOTVBFUlJfVU5LTk9XTl9SRVBPUlQ7CgogICAgaWYgKHBkdSA9PSBOVUxMIHx8IHBkdS0+dmFyaWFibGVzID09IE5VTEwpCiAgICAgICAgcmV0dXJuIHJwdF90eXBlOwogICAgdnAgPSBwZHUtPnZhcmlhYmxlczsKICAgIC8qIE1QRCBvciBVU00gYmFzZWQgcmVwb3J0IHN0YXRpc3RpY3Mgb2JqZWN0cyBoYXZlIHRoZSBzYW1lIGxlbmd0aCBwcmVmaXgKICAgICAqICAgc28gdGhlIGFjdHVhbCBzdGF0aXN0aWNzIE9JRCB3aWxsIGhhdmUgdGhpcyBsZW5ndGgsCiAgICAgKiAgIHBsdXMgb25lIHN1YmlkZW50aWZpZXIgZm9yIHRoZSBzY2FsYXIgTUlCIG9iamVjdCBpdHNlbGYsCiAgICAgKiAgIGFuZCBvbmUgZm9yIHRoZSBpbnN0YW5jZSBzdWJpZGVudGlmaWVyCiAgICAgKi8KICAgIGlmICh2cC0+bmFtZV9sZW5ndGggPT0gUkVQT1JUX1NUQVRTX0xFTiArIDIpIHsKICAgICAgICBpZiAobWVtY21wKHNubXBNUERTdGF0cywgdnAtPm5hbWUsIFJFUE9SVF9TVEFUU19MRU4gKiBzaXplb2Yob2lkKSkgPT0gMCkgewogICAgICAgICAgICBzd2l0Y2ggKHZwLT5uYW1lW1JFUE9SVF9TVEFUU19MRU5dKSB7CiAgICAgICAgICAgIGNhc2UgUkVQT1JUX3NubXBVbmtub3duU2VjdXJpdHlNb2RlbHNfTlVNOgogICAgICAgICAgICAgICAgcnB0X3R5cGUgPSBTTk1QRVJSX1VOS05PV05fU0VDX01PREVMOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgUkVQT1JUX3NubXBJbnZhbGlkTXNnc19OVU06CiAgICAgICAgICAgICAgICBycHRfdHlwZSA9IFNOTVBFUlJfSU5WQUxJRF9NU0c7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgY2FzZSBSRVBPUlRfc25tcFVua25vd25QRFVIYW5kbGVyc19OVU06CiAgICAgICAgICAgICAgICBycHRfdHlwZSA9IFNOTVBFUlJfQkFEX1ZFUlNJT047CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQogICAgICAgIH0gZWxzZSBpZiAobWVtY21wKHVzbVN0YXRzLCB2cC0+bmFtZSwgUkVQT1JUX1NUQVRTX0xFTiAqIHNpemVvZihvaWQpKSA9PSAwKSB7CiAgICAgICAgICAgIHN3aXRjaCAodnAtPm5hbWVbUkVQT1JUX1NUQVRTX0xFTl0pIHsKICAgICAgICAgICAgY2FzZSBSRVBPUlRfdXNtU3RhdHNVbnN1cHBvcnRlZFNlY0xldmVsc19OVU06CiAgICAgICAgICAgICAgICBycHRfdHlwZSA9IFNOTVBFUlJfVU5TVVBQT1JURURfU0VDX0xFVkVMOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgUkVQT1JUX3VzbVN0YXRzTm90SW5UaW1lV2luZG93c19OVU06CiAgICAgICAgICAgICAgICBycHRfdHlwZSA9IFNOTVBFUlJfTk9UX0lOX1RJTUVfV0lORE9XOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgUkVQT1JUX3VzbVN0YXRzVW5rbm93blVzZXJOYW1lc19OVU06CiAgICAgICAgICAgICAgICBycHRfdHlwZSA9IFNOTVBFUlJfVU5LTk9XTl9VU0VSX05BTUU7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgY2FzZSBSRVBPUlRfdXNtU3RhdHNVbmtub3duRW5naW5lSURzX05VTToKICAgICAgICAgICAgICAgIHJwdF90eXBlID0gU05NUEVSUl9VTktOT1dOX0VOR19JRDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlIFJFUE9SVF91c21TdGF0c1dyb25nRGlnZXN0c19OVU06CiAgICAgICAgICAgICAgICBycHRfdHlwZSA9IFNOTVBFUlJfQVVUSEVOVElDQVRJT05fRkFJTFVSRTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlIFJFUE9SVF91c21TdGF0c0RlY3J5cHRpb25FcnJvcnNfTlVNOgogICAgICAgICAgICAgICAgcnB0X3R5cGUgPSBTTk1QRVJSX0RFQ1JZUFRJT05fRVJSOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CiAgICAvKiBDb250ZXh0LWJhc2VkIHJlcG9ydCBzdGF0aXN0aWNzIGZyb20gdGhlIFRhcmdldCBNSUIgYXJlIHNpbWlsYXIKICAgICAqICAgYnV0IHRoZSBPSUQgcHJlZml4IGhhcyBhIGRpZmZlcmVudCBsZW5ndGgKICAgICAqLwogICAgaWYgKHZwLT5uYW1lX2xlbmd0aCA9PSBSRVBPUlRfU1RBVFNfTEVOMiArIDIpIHsKICAgICAgICBpZiAobWVtY21wKHRhcmdldFN0YXRzLCB2cC0+bmFtZSwgUkVQT1JUX1NUQVRTX0xFTjIgKiBzaXplb2Yob2lkKSkgPT0gMCkgewogICAgICAgICAgICBzd2l0Y2ggKHZwLT5uYW1lW1JFUE9SVF9TVEFUU19MRU4yXSkgewogICAgICAgICAgICBjYXNlIFJFUE9SVF9zbm1wVW5hdmFpbGFibGVDb250ZXh0c19OVU06CiAgICAgICAgICAgICAgICBycHRfdHlwZSA9IFNOTVBFUlJfQkFEX0NPTlRFWFQ7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgY2FzZSBSRVBPUlRfc25tcFVua25vd25Db250ZXh0c19OVU06CiAgICAgICAgICAgICAgICBycHRfdHlwZSA9IFNOTVBFUlJfQkFEX0NPTlRFWFQ7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KICAgIERFQlVHTVNHVEwoKCJyZXBvcnQiLCAiUmVwb3J0IHR5cGU6ICVkXG4iLCBycHRfdHlwZSkpOwogICAgcmV0dXJuIHJwdF90eXBlOwp9CgovKgogKiBQYXJzZXMgdGhlIHBhY2tldCByZWNlaXZlZCBvbiB0aGUgaW5wdXQgc2Vzc2lvbiwgYW5kIHBsYWNlcyB0aGUgZGF0YSBpbnRvCiAqIHRoZSBpbnB1dCBwZHUuICBsZW5ndGggaXMgdGhlIGxlbmd0aCBvZiB0aGUgaW5wdXQgcGFja2V0LgogKiBJZiBhbnkgZXJyb3JzIGFyZSBlbmNvdW50ZXJlZCwgLTEgb3IgVVNNIGVycm9yIGlzIHJldHVybmVkLgogKiBPdGhlcndpc2UsIGEgMCBpcyByZXR1cm5lZC4KICovCnN0YXRpYyBpbnQKX3NubXBfcGFyc2Uodm9pZCAqc2Vzc3AsCiAgICAgICAgICAgIG5ldHNubXBfc2Vzc2lvbiAqIHNlc3Npb24sCiAgICAgICAgICAgIG5ldHNubXBfcGR1ICpwZHUsIHVfY2hhciAqIGRhdGEsIHNpemVfdCBsZW5ndGgpCnsKI2lmICFkZWZpbmVkKE5FVFNOTVBfRElTQUJMRV9TTk1QVjEpIHx8ICFkZWZpbmVkKE5FVFNOTVBfRElTQUJMRV9TTk1QVjJDKQogICAgdV9jaGFyICAgICAgICAgIGNvbW11bml0eVtDT01NVU5JVFlfTUFYX0xFTl07CiAgICBzaXplX3QgICAgICAgICAgY29tbXVuaXR5X2xlbmd0aCA9IENPTU1VTklUWV9NQVhfTEVOOwojZW5kaWYKICAgIGludCAgICAgICAgICAgICByZXN1bHQgPSAtMTsKCiAgICBzZXNzaW9uLT5zX3NubXBfZXJybm8gPSAwOwogICAgc2Vzc2lvbi0+c19lcnJubyA9IDA7CgogICAgLyoKICAgICAqIEVuc3VyZSBhbGwgaW5jb21pbmcgUERVcyBoYXZlIGEgdW5pcXVlIG1lYW5zIG9mIGlkZW50aWZpY2F0aW9uIAogICAgICogKFRoaXMgaXMgbm90IHJlc3RyaWN0ZWQgdG8gQWdlbnRYIGhhbmRsaW5nLAogICAgICogdGhvdWdoIHRoYXQgaXMgd2hlcmUgdGhlIG5lZWQgYmVjb21lcyB2aXNpYmxlKSAgIAogICAgICovCiAgICBwZHUtPnRyYW5zaWQgPSBzbm1wX2dldF9uZXh0X3RyYW5zaWQoKTsKCiAgICBpZiAoc2Vzc2lvbi0+dmVyc2lvbiAhPSBTTk1QX0RFRkFVTFRfVkVSU0lPTikgewogICAgICAgIHBkdS0+dmVyc2lvbiA9IHNlc3Npb24tPnZlcnNpb247CiAgICB9IGVsc2UgewogICAgICAgIHBkdS0+dmVyc2lvbiA9IHNubXBfcGFyc2VfdmVyc2lvbihkYXRhLCBsZW5ndGgpOwogICAgfQoKICAgIHN3aXRjaCAocGR1LT52ZXJzaW9uKSB7CiNpZm5kZWYgTkVUU05NUF9ESVNBQkxFX1NOTVBWMQogICAgY2FzZSBTTk1QX1ZFUlNJT05fMToKI2VuZGlmCiNpZm5kZWYgTkVUU05NUF9ESVNBQkxFX1NOTVBWMkMKICAgIGNhc2UgU05NUF9WRVJTSU9OXzJjOgojZW5kaWYKI2lmICFkZWZpbmVkKE5FVFNOTVBfRElTQUJMRV9TTk1QVjEpIHx8ICFkZWZpbmVkKE5FVFNOTVBfRElTQUJMRV9TTk1QVjJDKQogICAgICAgIERFQlVHTVNHVEwoKCJzbm1wX2FwaSIsICJQYXJzaW5nIFNOTVB2JWQgbWVzc2FnZS4uLlxuIiwKICAgICAgICAgICAgICAgICAgICAoMSArIHBkdS0+dmVyc2lvbikpKTsKCiAgICAgICAgLyoKICAgICAgICAgKiBhdXRoZW50aWNhdGVzIG1lc3NhZ2UgYW5kIHJldHVybnMgbGVuZ3RoIGlmIHZhbGlkIAogICAgICAgICAqLwojaWZuZGVmIE5FVFNOTVBfRElTQUJMRV9TTk1QVjEKICAgICAgICBpZiAocGR1LT52ZXJzaW9uID09IFNOTVBfVkVSU0lPTl8xKSB7CiAgICAgICAgICAgIERFQlVHRFVNUFNFQ1RJT04oInJlY3YiLCAiU05NUHYxIG1lc3NhZ2VcbiIpOwogICAgICAgIH0gZWxzZSB7CiNlbmRpZgogICAgICAgICAgICBERUJVR0RVTVBTRUNUSU9OKCJyZWN2IiwgIlNOTVB2MmMgbWVzc2FnZVxuIik7CiNpZm5kZWYgTkVUU05NUF9ESVNBQkxFX1NOTVBWMQogICAgICAgIH0KI2VuZGlmCiAgICAgICAgZGF0YSA9IHNubXBfY29tc3RyX3BhcnNlKGRhdGEsICZsZW5ndGgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbW11bml0eSwgJmNvbW11bml0eV9sZW5ndGgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZwZHUtPnZlcnNpb24pOwogICAgICAgIGlmIChkYXRhID09IE5VTEwpCiAgICAgICAgICAgIHJldHVybiAtMTsKCiAgICAgICAgaWYgKHBkdS0+dmVyc2lvbiAhPSBzZXNzaW9uLT52ZXJzaW9uICYmCiAgICAgICAgICAgIHNlc3Npb24tPnZlcnNpb24gIT0gU05NUF9ERUZBVUxUX1ZFUlNJT04pIHsKICAgICAgICAgICAgc2Vzc2lvbi0+c19zbm1wX2Vycm5vID0gU05NUEVSUl9CQURfVkVSU0lPTjsKICAgICAgICAgICAgcmV0dXJuIC0xOwogICAgICAgIH0KCiAgICAgICAgLyoKICAgICAgICAgKiBtYXliZSBnZXQgdGhlIGNvbW11bml0eSBzdHJpbmcuIAogICAgICAgICAqLwogICAgICAgIHBkdS0+c2VjdXJpdHlMZXZlbCA9IFNOTVBfU0VDX0xFVkVMX05PQVVUSDsKICAgICAgICBwZHUtPnNlY3VyaXR5TW9kZWwgPSAKI2lmbmRlZiBORVRTTk1QX0RJU0FCTEVfU05NUFYxCiAgICAgICAgICAgIChwZHUtPnZlcnNpb24gPT0gU05NUF9WRVJTSU9OXzEpID8gU05NUF9TRUNfTU9ERUxfU05NUHYxIDogCiNlbmRpZgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNOTVBfU0VDX01PREVMX1NOTVB2MmM7CiAgICAgICAgU05NUF9GUkVFKHBkdS0+Y29tbXVuaXR5KTsKICAgICAgICBwZHUtPmNvbW11bml0eV9sZW4gPSAwOwogICAgICAgIHBkdS0+Y29tbXVuaXR5ID0gKHVfY2hhciAqKSAwOwogICAgICAgIGlmIChjb21tdW5pdHlfbGVuZ3RoKSB7CiAgICAgICAgICAgIHBkdS0+Y29tbXVuaXR5X2xlbiA9IGNvbW11bml0eV9sZW5ndGg7CiAgICAgICAgICAgIHBkdS0+Y29tbXVuaXR5ID0gKHVfY2hhciAqKSBtYWxsb2MoY29tbXVuaXR5X2xlbmd0aCk7CiAgICAgICAgICAgIGlmIChwZHUtPmNvbW11bml0eSA9PSBOVUxMKSB7CiAgICAgICAgICAgICAgICBzZXNzaW9uLT5zX3NubXBfZXJybm8gPSBTTk1QRVJSX01BTExPQzsKICAgICAgICAgICAgICAgIHJldHVybiAtMTsKICAgICAgICAgICAgfQogICAgICAgICAgICBtZW1tb3ZlKHBkdS0+Y29tbXVuaXR5LCBjb21tdW5pdHksIGNvbW11bml0eV9sZW5ndGgpOwogICAgICAgIH0KICAgICAgICBpZiAoc2Vzc2lvbi0+YXV0aGVudGljYXRvcikgewogICAgICAgICAgICBkYXRhID0gc2Vzc2lvbi0+YXV0aGVudGljYXRvcihkYXRhLCAmbGVuZ3RoLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb21tdW5pdHksIGNvbW11bml0eV9sZW5ndGgpOwogICAgICAgICAgICBpZiAoZGF0YSA9PSBOVUxMKSB7CiAgICAgICAgICAgICAgICBzZXNzaW9uLT5zX3NubXBfZXJybm8gPSBTTk1QRVJSX0FVVEhFTlRJQ0FUSU9OX0ZBSUxVUkU7CiAgICAgICAgICAgICAgICByZXR1cm4gLTE7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIERFQlVHRFVNUFNFQ1RJT04oInJlY3YiLCAiUERVIik7CiAgICAgICAgcmVzdWx0ID0gc25tcF9wZHVfcGFyc2UocGR1LCBkYXRhLCAmbGVuZ3RoKTsKICAgICAgICBpZiAocmVzdWx0IDwgMCkgewogICAgICAgICAgICAvKgogICAgICAgICAgICAgKiBUaGlzIGluZGljYXRlcyBhIHBhcnNlIGVycm9yLiAgCiAgICAgICAgICAgICAqLwogICAgICAgICAgICBzbm1wX2luY3JlbWVudF9zdGF0aXN0aWMoU1RBVF9TTk1QSU5BU05QQVJTRUVSUlMpOwogICAgICAgIH0KICAgICAgICBERUJVR0lOREVOVEFERCgtNik7CiAgICAgICAgYnJlYWs7CiNlbmRpZiAvKiBzdXBwb3J0IGZvciBjb21tdW5pdHkgYmFzZWQgU05NUCAqLwoKICAgIGNhc2UgU05NUF9WRVJTSU9OXzM6CiAgICAgICAgcmVzdWx0ID0gc25tcHYzX3BhcnNlKHBkdSwgZGF0YSwgJmxlbmd0aCwgTlVMTCwgc2Vzc2lvbik7CiAgICAgICAgREVCVUdNU0dUTCgoInNubXBfcGFyc2UiLAogICAgICAgICAgICAgICAgICAgICJQYXJzZWQgU05NUHYzIG1lc3NhZ2UgKHNlY05hbWU6JXMsIHNlY0xldmVsOiVzKTogJXNcbiIsCiAgICAgICAgICAgICAgICAgICAgcGR1LT5zZWN1cml0eU5hbWUsIHNlY0xldmVsTmFtZVtwZHUtPnNlY3VyaXR5TGV2ZWxdLAogICAgICAgICAgICAgICAgICAgIHNubXBfYXBpX2VycnN0cmluZyhyZXN1bHQpKSk7CgogICAgICAgIGlmIChyZXN1bHQpIHsKICAgICAgICAgICAgc3RydWN0IHNubXBfc2VjbW9kX2RlZiAqc2VjbW9kID0KICAgICAgICAgICAgICAgIGZpbmRfc2VjX21vZChwZHUtPnNlY3VyaXR5TW9kZWwpOwogICAgICAgICAgICBpZiAoIXNlc3NwKSB7CiAgICAgICAgICAgICAgICBzZXNzaW9uLT5zX3NubXBfZXJybm8gPSByZXN1bHQ7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAvKgogICAgICAgICAgICAgICAgICogQ2FsbCB0aGUgc2VjdXJpdHkgbW9kZWwgdG8gc3BlY2lhbCBoYW5kbGUgYW55IGVycm9ycwogICAgICAgICAgICAgICAgICovCgogICAgICAgICAgICAgICAgaWYgKHNlY21vZCAmJiBzZWNtb2QtPmhhbmRsZV9yZXBvcnQpIHsKICAgICAgICAgICAgICAgICAgICBzdHJ1Y3Qgc2Vzc2lvbl9saXN0ICpzbHAgPSAoc3RydWN0IHNlc3Npb25fbGlzdCAqKSBzZXNzcDsKICAgICAgICAgICAgICAgICAgICAoKnNlY21vZC0+aGFuZGxlX3JlcG9ydCkoc2Vzc3AsIHNscC0+dHJhbnNwb3J0LCBzZXNzaW9uLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXN1bHQsIHBkdSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKHBkdS0+c2VjdXJpdHlTdGF0ZVJlZiAhPSBOVUxMKSB7CiAgICAgICAgICAgICAgICBpZiAoc2VjbW9kICYmIHNlY21vZC0+cGR1X2ZyZWVfc3RhdGVfcmVmKSB7CiAgICAgICAgICAgICAgICAgICAgc2VjbW9kLT5wZHVfZnJlZV9zdGF0ZV9yZWYocGR1LT5zZWN1cml0eVN0YXRlUmVmKTsKICAgICAgICAgICAgICAgICAgICBwZHUtPnNlY3VyaXR5U3RhdGVSZWYgPSBOVUxMOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGJyZWFrOwogICAgY2FzZSBTTk1QRVJSX0JBRF9WRVJTSU9OOgogICAgICAgIEVSUk9SX01TRygiZXJyb3IgcGFyc2luZyBzbm1wIG1lc3NhZ2UgdmVyc2lvbiIpOwogICAgICAgIHNubXBfaW5jcmVtZW50X3N0YXRpc3RpYyhTVEFUX1NOTVBJTkFTTlBBUlNFRVJSUyk7CiAgICAgICAgc2Vzc2lvbi0+c19zbm1wX2Vycm5vID0gU05NUEVSUl9CQURfVkVSU0lPTjsKICAgICAgICBicmVhazsKICAgIGNhc2UgU05NUF9WRVJTSU9OX3NlYzoKICAgIGNhc2UgU05NUF9WRVJTSU9OXzJ1OgogICAgY2FzZSBTTk1QX1ZFUlNJT05fMnN0YXI6CiAgICBjYXNlIFNOTVBfVkVSU0lPTl8ycDoKICAgIGRlZmF1bHQ6CiAgICAgICAgRVJST1JfTVNHKCJ1bnN1cHBvcnRlZCBzbm1wIG1lc3NhZ2UgdmVyc2lvbiIpOwogICAgICAgIHNubXBfaW5jcmVtZW50X3N0YXRpc3RpYyhTVEFUX1NOTVBJTkJBRFZFUlNJT05TKTsKCiAgICAgICAgLyoKICAgICAgICAgKiBuZWVkIGJldHRlciB3YXkgdG8gZGV0ZXJtaW5lIE9TIGluZGVwZW5kZW50CiAgICAgICAgICogSU5UMzJfTUFYIHZhbHVlLCBmb3Igbm93IGhhcmRjb2RlCiAgICAgICAgICovCiAgICAgICAgaWYgKHBkdS0+dmVyc2lvbiA8IDAgfHwgcGR1LT52ZXJzaW9uID4gMjE0NzQ4MzY0NykgewogICAgICAgICAgICBzbm1wX2luY3JlbWVudF9zdGF0aXN0aWMoU1RBVF9TTk1QSU5BU05QQVJTRUVSUlMpOwogICAgICAgIH0KICAgICAgICBzZXNzaW9uLT5zX3NubXBfZXJybm8gPSBTTk1QRVJSX0JBRF9WRVJTSU9OOwogICAgICAgIGJyZWFrOwogICAgfQoKICAgIHJldHVybiByZXN1bHQ7Cn0KCnN0YXRpYyBpbnQKc25tcF9wYXJzZSh2b2lkICpzZXNzcCwKICAgICAgICAgICBuZXRzbm1wX3Nlc3Npb24gKiBwc3MsCiAgICAgICAgICAgbmV0c25tcF9wZHUgKnBkdSwgdV9jaGFyICogZGF0YSwgc2l6ZV90IGxlbmd0aCkKewogICAgaW50ICAgICAgICAgICAgIHJjOwoKICAgIHJjID0gX3NubXBfcGFyc2Uoc2Vzc3AsIHBzcywgcGR1LCBkYXRhLCBsZW5ndGgpOwogICAgaWYgKHJjKSB7CiAgICAgICAgaWYgKCFwc3MtPnNfc25tcF9lcnJubykgewogICAgICAgICAgICBwc3MtPnNfc25tcF9lcnJubyA9IFNOTVBFUlJfQkFEX1BBUlNFOwogICAgICAgIH0KICAgICAgICBTRVRfU05NUF9FUlJPUihwc3MtPnNfc25tcF9lcnJubyk7CiAgICB9CgogICAgcmV0dXJuIHJjOwp9CgppbnQKc25tcF9wZHVfcGFyc2UobmV0c25tcF9wZHUgKnBkdSwgdV9jaGFyICogZGF0YSwgc2l6ZV90ICogbGVuZ3RoKQp7CiAgICB1X2NoYXIgICAgICAgICAgdHlwZTsKICAgIHVfY2hhciAgICAgICAgICBtc2dfdHlwZTsKICAgIHVfY2hhciAgICAgICAgICp2YXJfdmFsOwogICAgaW50ICAgICAgICAgICAgIGJhZHR5cGUgPSAwOwogICAgc2l6ZV90ICAgICAgICAgIGxlbjsKICAgIHNpemVfdCAgICAgICAgICBmb3VyOwogICAgbmV0c25tcF92YXJpYWJsZV9saXN0ICp2cCA9IE5VTEw7CiAgICBvaWQgICAgICAgICAgICAgb2JqaWRbTUFYX09JRF9MRU5dOwoKICAgIC8qCiAgICAgKiBHZXQgdGhlIFBEVSB0eXBlIAogICAgICovCiAgICBkYXRhID0gYXNuX3BhcnNlX2hlYWRlcihkYXRhLCBsZW5ndGgsICZtc2dfdHlwZSk7CiAgICBpZiAoZGF0YSA9PSBOVUxMKQogICAgICAgIHJldHVybiAtMTsKICAgIERFQlVHTVNHVEwoKCJkdW1wdl9yZWN2IiwiICAgIENvbW1hbmQgJXNcbiIsIHNubXBfcGR1X3R5cGUobXNnX3R5cGUpKSk7CiAgICBwZHUtPmNvbW1hbmQgPSBtc2dfdHlwZTsKICAgIHBkdS0+ZmxhZ3MgJj0gKH5VQ0RfTVNHX0ZMQUdfUkVTUE9OU0VfUERVKTsKCiAgICAvKgogICAgICogZ2V0IHRoZSBmaWVsZHMgaW4gdGhlIFBEVSBwcmVjZWVkaW5nIHRoZSB2YXJpYWJsZS1iaW5kaW5ncyBzZXF1ZW5jZSAKICAgICAqLwogICAgc3dpdGNoIChwZHUtPmNvbW1hbmQpIHsKICAgIGNhc2UgU05NUF9NU0dfVFJBUDoKICAgICAgICAvKgogICAgICAgICAqIGVudGVycHJpc2UgCiAgICAgICAgICovCiAgICAgICAgcGR1LT5lbnRlcnByaXNlX2xlbmd0aCA9IE1BWF9PSURfTEVOOwogICAgICAgIGRhdGEgPSBhc25fcGFyc2Vfb2JqaWQoZGF0YSwgbGVuZ3RoLCAmdHlwZSwgb2JqaWQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmcGR1LT5lbnRlcnByaXNlX2xlbmd0aCk7CiAgICAgICAgaWYgKGRhdGEgPT0gTlVMTCkKICAgICAgICAgICAgcmV0dXJuIC0xOwogICAgICAgIHBkdS0+ZW50ZXJwcmlzZSA9CiAgICAgICAgICAgIChvaWQgKikgbWFsbG9jKHBkdS0+ZW50ZXJwcmlzZV9sZW5ndGggKiBzaXplb2Yob2lkKSk7CiAgICAgICAgaWYgKHBkdS0+ZW50ZXJwcmlzZSA9PSBOVUxMKSB7CiAgICAgICAgICAgIHJldHVybiAtMTsKICAgICAgICB9CiAgICAgICAgbWVtbW92ZShwZHUtPmVudGVycHJpc2UsIG9iamlkLAogICAgICAgICAgICAgICAgcGR1LT5lbnRlcnByaXNlX2xlbmd0aCAqIHNpemVvZihvaWQpKTsKCiAgICAgICAgLyoKICAgICAgICAgKiBhZ2VudC1hZGRyIAogICAgICAgICAqLwogICAgICAgIGZvdXIgPSA0OwogICAgICAgIGRhdGEgPSBhc25fcGFyc2Vfc3RyaW5nKGRhdGEsIGxlbmd0aCwgJnR5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKHVfY2hhciAqKSBwZHUtPmFnZW50X2FkZHIsICZmb3VyKTsKICAgICAgICBpZiAoZGF0YSA9PSBOVUxMKQogICAgICAgICAgICByZXR1cm4gLTE7CgogICAgICAgIC8qCiAgICAgICAgICogZ2VuZXJpYyB0cmFwIAogICAgICAgICAqLwogICAgICAgIGRhdGEgPSBhc25fcGFyc2VfaW50KGRhdGEsIGxlbmd0aCwgJnR5cGUsIChsb25nICopICZwZHUtPnRyYXBfdHlwZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaXplb2YocGR1LT50cmFwX3R5cGUpKTsKICAgICAgICBpZiAoZGF0YSA9PSBOVUxMKQogICAgICAgICAgICByZXR1cm4gLTE7CiAgICAgICAgLyoKICAgICAgICAgKiBzcGVjaWZpYyB0cmFwIAogICAgICAgICAqLwogICAgICAgIGRhdGEgPQogICAgICAgICAgICBhc25fcGFyc2VfaW50KGRhdGEsIGxlbmd0aCwgJnR5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgKGxvbmcgKikgJnBkdS0+c3BlY2lmaWNfdHlwZSwKICAgICAgICAgICAgICAgICAgICAgICAgICBzaXplb2YocGR1LT5zcGVjaWZpY190eXBlKSk7CiAgICAgICAgaWYgKGRhdGEgPT0gTlVMTCkKICAgICAgICAgICAgcmV0dXJuIC0xOwoKICAgICAgICAvKgogICAgICAgICAqIHRpbWVzdGFtcCAgCiAgICAgICAgICovCiAgICAgICAgZGF0YSA9IGFzbl9wYXJzZV91bnNpZ25lZF9pbnQoZGF0YSwgbGVuZ3RoLCAmdHlwZSwgJnBkdS0+dGltZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaXplb2YocGR1LT50aW1lKSk7CiAgICAgICAgaWYgKGRhdGEgPT0gTlVMTCkKICAgICAgICAgICAgcmV0dXJuIC0xOwoKICAgICAgICBicmVhazsKCiAgICBjYXNlIFNOTVBfTVNHX1JFU1BPTlNFOgogICAgY2FzZSBTTk1QX01TR19SRVBPUlQ6CiAgICAgICAgcGR1LT5mbGFncyB8PSBVQ0RfTVNHX0ZMQUdfUkVTUE9OU0VfUERVOwogICAgICAgIC8qCiAgICAgICAgICogZmFsbHRocm91Z2ggCiAgICAgICAgICovCgogICAgY2FzZSBTTk1QX01TR19HRVQ6CiAgICBjYXNlIFNOTVBfTVNHX0dFVE5FWFQ6CiAgICBjYXNlIFNOTVBfTVNHX0dFVEJVTEs6CiAgICBjYXNlIFNOTVBfTVNHX1RSQVAyOgogICAgY2FzZSBTTk1QX01TR19JTkZPUk06CiAgICBjYXNlIFNOTVBfTVNHX1NFVDoKICAgICAgICAvKgogICAgICAgICAqIFBEVSBpcyBub3QgYW4gU05NUHYxIFRSQVAgCiAgICAgICAgICovCgogICAgICAgIC8qCiAgICAgICAgICogcmVxdWVzdCBpZCAKICAgICAgICAgKi8KICAgICAgICBERUJVR0RVTVBIRUFERVIoInJlY3YiLCAicmVxdWVzdF9pZCIpOwogICAgICAgIGRhdGEgPSBhc25fcGFyc2VfaW50KGRhdGEsIGxlbmd0aCwgJnR5cGUsICZwZHUtPnJlcWlkLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNpemVvZihwZHUtPnJlcWlkKSk7CiAgICAgICAgREVCVUdJTkRFTlRMRVNTKCk7CiAgICAgICAgaWYgKGRhdGEgPT0gTlVMTCkgewogICAgICAgICAgICByZXR1cm4gLTE7CiAgICAgICAgfQoKICAgICAgICAvKgogICAgICAgICAqIGVycm9yIHN0YXR1cyAoZ2V0YnVsayBub24tcmVwZWF0ZXJzKSAKICAgICAgICAgKi8KICAgICAgICBERUJVR0RVTVBIRUFERVIoInJlY3YiLCAiZXJyb3Igc3RhdHVzIik7CiAgICAgICAgZGF0YSA9IGFzbl9wYXJzZV9pbnQoZGF0YSwgbGVuZ3RoLCAmdHlwZSwgJnBkdS0+ZXJyc3RhdCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaXplb2YocGR1LT5lcnJzdGF0KSk7CiAgICAgICAgREVCVUdJTkRFTlRMRVNTKCk7CiAgICAgICAgaWYgKGRhdGEgPT0gTlVMTCkgewogICAgICAgICAgICByZXR1cm4gLTE7CiAgICAgICAgfQoKICAgICAgICAvKgogICAgICAgICAqIGVycm9yIGluZGV4IChnZXRidWxrIG1heC1yZXBldGl0aW9ucykgCiAgICAgICAgICovCiAgICAgICAgREVCVUdEVU1QSEVBREVSKCJyZWN2IiwgImVycm9yIGluZGV4Iik7CiAgICAgICAgZGF0YSA9IGFzbl9wYXJzZV9pbnQoZGF0YSwgbGVuZ3RoLCAmdHlwZSwgJnBkdS0+ZXJyaW5kZXgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2l6ZW9mKHBkdS0+ZXJyaW5kZXgpKTsKICAgICAgICBERUJVR0lOREVOVExFU1MoKTsKICAgICAgICBpZiAoZGF0YSA9PSBOVUxMKSB7CiAgICAgICAgICAgIHJldHVybiAtMTsKICAgICAgICB9CglicmVhazsKCiAgICBkZWZhdWx0OgogICAgICAgIHNubXBfbG9nKExPR19FUlIsICJCYWQgUERVIHR5cGUgcmVjZWl2ZWQ6IDB4JS4yeFxuIiwgcGR1LT5jb21tYW5kKTsKICAgICAgICBzbm1wX2luY3JlbWVudF9zdGF0aXN0aWMoU1RBVF9TTk1QSU5BU05QQVJTRUVSUlMpOwogICAgICAgIHJldHVybiAtMTsKICAgIH0KCiAgICAvKgogICAgICogZ2V0IGhlYWRlciBmb3IgdmFyaWFibGUtYmluZGluZ3Mgc2VxdWVuY2UgCiAgICAgKi8KICAgIERFQlVHRFVNUFNFQ1RJT04oInJlY3YiLCAiVmFyQmluZExpc3QiKTsKICAgIGRhdGEgPSBhc25fcGFyc2Vfc2VxdWVuY2UoZGF0YSwgbGVuZ3RoLCAmdHlwZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKEFTTl9TRVFVRU5DRSB8IEFTTl9DT05TVFJVQ1RPUiksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJ2YXJiaW5kcyIpOwogICAgaWYgKGRhdGEgPT0gTlVMTCkKICAgICAgICByZXR1cm4gLTE7CgogICAgLyoKICAgICAqIGdldCBlYWNoIHZhckJpbmQgc2VxdWVuY2UgCiAgICAgKi8KICAgIHdoaWxlICgoaW50KSAqbGVuZ3RoID4gMCkgewogICAgICAgIG5ldHNubXBfdmFyaWFibGVfbGlzdCAqdnB0ZW1wOwogICAgICAgIHZwdGVtcCA9IChuZXRzbm1wX3ZhcmlhYmxlX2xpc3QgKikgbWFsbG9jKHNpemVvZigqdnB0ZW1wKSk7CiAgICAgICAgaWYgKDAgPT0gdnB0ZW1wKSB7CiAgICAgICAgICAgIHJldHVybiAtMTsKICAgICAgICB9CiAgICAgICAgaWYgKDAgPT0gdnApIHsKICAgICAgICAgICAgcGR1LT52YXJpYWJsZXMgPSB2cHRlbXA7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgdnAtPm5leHRfdmFyaWFibGUgPSB2cHRlbXA7CiAgICAgICAgfQogICAgICAgIHZwID0gdnB0ZW1wOwoKICAgICAgICB2cC0+bmV4dF92YXJpYWJsZSA9IE5VTEw7CiAgICAgICAgdnAtPnZhbC5zdHJpbmcgPSBOVUxMOwogICAgICAgIHZwLT5uYW1lX2xlbmd0aCA9IE1BWF9PSURfTEVOOwogICAgICAgIHZwLT5uYW1lID0gMDsKICAgICAgICB2cC0+aW5kZXggPSAwOwogICAgICAgIHZwLT5kYXRhID0gMDsKICAgICAgICB2cC0+ZGF0YUZyZWVIb29rID0gMDsKICAgICAgICBERUJVR0RVTVBTRUNUSU9OKCJyZWN2IiwgIlZhckJpbmQiKTsKICAgICAgICBkYXRhID0gc25tcF9wYXJzZV92YXJfb3AoZGF0YSwgb2JqaWQsICZ2cC0+bmFtZV9sZW5ndGgsICZ2cC0+dHlwZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJnZwLT52YWxfbGVuLCAmdmFyX3ZhbCwgbGVuZ3RoKTsKICAgICAgICBpZiAoZGF0YSA9PSBOVUxMKQogICAgICAgICAgICByZXR1cm4gLTE7CiAgICAgICAgaWYgKHNubXBfc2V0X3Zhcl9vYmppZCh2cCwgb2JqaWQsIHZwLT5uYW1lX2xlbmd0aCkpCiAgICAgICAgICAgIHJldHVybiAtMTsKCiAgICAgICAgbGVuID0gTUFYX1BBQ0tFVF9MRU5HVEg7CiAgICAgICAgREVCVUdEVU1QSEVBREVSKCJyZWN2IiwgIlZhbHVlIik7CiAgICAgICAgc3dpdGNoICgoc2hvcnQpIHZwLT50eXBlKSB7CiAgICAgICAgY2FzZSBBU05fSU5URUdFUjoKICAgICAgICAgICAgdnAtPnZhbC5pbnRlZ2VyID0gKGxvbmcgKikgdnAtPmJ1ZjsKICAgICAgICAgICAgdnAtPnZhbF9sZW4gPSBzaXplb2YobG9uZyk7CiAgICAgICAgICAgIGFzbl9wYXJzZV9pbnQodmFyX3ZhbCwgJmxlbiwgJnZwLT50eXBlLAogICAgICAgICAgICAgICAgICAgICAgICAgIChsb25nICopIHZwLT52YWwuaW50ZWdlciwKICAgICAgICAgICAgICAgICAgICAgICAgICBzaXplb2YoKnZwLT52YWwuaW50ZWdlcikpOwogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIEFTTl9DT1VOVEVSOgogICAgICAgIGNhc2UgQVNOX0dBVUdFOgogICAgICAgIGNhc2UgQVNOX1RJTUVUSUNLUzoKICAgICAgICBjYXNlIEFTTl9VSU5URUdFUjoKICAgICAgICAgICAgdnAtPnZhbC5pbnRlZ2VyID0gKGxvbmcgKikgdnAtPmJ1ZjsKICAgICAgICAgICAgdnAtPnZhbF9sZW4gPSBzaXplb2YodV9sb25nKTsKICAgICAgICAgICAgYXNuX3BhcnNlX3Vuc2lnbmVkX2ludCh2YXJfdmFsLCAmbGVuLCAmdnAtPnR5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKHVfbG9uZyAqKSB2cC0+dmFsLmludGVnZXIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdnAtPnZhbF9sZW4pOwogICAgICAgICAgICBicmVhazsKI2lmZGVmIE5FVFNOTVBfV0lUSF9PUEFRVUVfU1BFQ0lBTF9UWVBFUwogICAgICAgIGNhc2UgQVNOX09QQVFVRV9DT1VOVEVSNjQ6CiAgICAgICAgY2FzZSBBU05fT1BBUVVFX1U2NDoKI2VuZGlmICAgICAgICAgICAgICAgICAgICAgICAgICAvKiBORVRTTk1QX1dJVEhfT1BBUVVFX1NQRUNJQUxfVFlQRVMgKi8KICAgICAgICBjYXNlIEFTTl9DT1VOVEVSNjQ6CiAgICAgICAgICAgIHZwLT52YWwuY291bnRlcjY0ID0gKHN0cnVjdCBjb3VudGVyNjQgKikgdnAtPmJ1ZjsKICAgICAgICAgICAgdnAtPnZhbF9sZW4gPSBzaXplb2Yoc3RydWN0IGNvdW50ZXI2NCk7CiAgICAgICAgICAgIGFzbl9wYXJzZV91bnNpZ25lZF9pbnQ2NCh2YXJfdmFsLCAmbGVuLCAmdnAtPnR5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoc3RydWN0IGNvdW50ZXI2NCAqKSB2cC0+dmFsLgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY291bnRlcjY0LCB2cC0+dmFsX2xlbik7CiAgICAgICAgICAgIGJyZWFrOwojaWZkZWYgTkVUU05NUF9XSVRIX09QQVFVRV9TUEVDSUFMX1RZUEVTCiAgICAgICAgY2FzZSBBU05fT1BBUVVFX0ZMT0FUOgogICAgICAgICAgICB2cC0+dmFsLmZsb2F0VmFsID0gKGZsb2F0ICopIHZwLT5idWY7CiAgICAgICAgICAgIHZwLT52YWxfbGVuID0gc2l6ZW9mKGZsb2F0KTsKICAgICAgICAgICAgYXNuX3BhcnNlX2Zsb2F0KHZhcl92YWwsICZsZW4sICZ2cC0+dHlwZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZwLT52YWwuZmxvYXRWYWwsIHZwLT52YWxfbGVuKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSBBU05fT1BBUVVFX0RPVUJMRToKICAgICAgICAgICAgdnAtPnZhbC5kb3VibGVWYWwgPSAoZG91YmxlICopIHZwLT5idWY7CiAgICAgICAgICAgIHZwLT52YWxfbGVuID0gc2l6ZW9mKGRvdWJsZSk7CiAgICAgICAgICAgIGFzbl9wYXJzZV9kb3VibGUodmFyX3ZhbCwgJmxlbiwgJnZwLT50eXBlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZwLT52YWwuZG91YmxlVmFsLCB2cC0+dmFsX2xlbik7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgQVNOX09QQVFVRV9JNjQ6CiAgICAgICAgICAgIHZwLT52YWwuY291bnRlcjY0ID0gKHN0cnVjdCBjb3VudGVyNjQgKikgdnAtPmJ1ZjsKICAgICAgICAgICAgdnAtPnZhbF9sZW4gPSBzaXplb2Yoc3RydWN0IGNvdW50ZXI2NCk7CiAgICAgICAgICAgIGFzbl9wYXJzZV9zaWduZWRfaW50NjQodmFyX3ZhbCwgJmxlbiwgJnZwLT50eXBlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChzdHJ1Y3QgY291bnRlcjY0ICopIHZwLT52YWwuY291bnRlcjY0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNpemVvZigqdnAtPnZhbC5jb3VudGVyNjQpKTsKCiAgICAgICAgICAgIGJyZWFrOwojZW5kaWYgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIE5FVFNOTVBfV0lUSF9PUEFRVUVfU1BFQ0lBTF9UWVBFUyAqLwogICAgICAgIGNhc2UgQVNOX09DVEVUX1NUUjoKICAgICAgICBjYXNlIEFTTl9JUEFERFJFU1M6CiAgICAgICAgY2FzZSBBU05fT1BBUVVFOgogICAgICAgIGNhc2UgQVNOX05TQVA6CiAgICAgICAgICAgIGlmICh2cC0+dmFsX2xlbiA8IHNpemVvZih2cC0+YnVmKSkgewogICAgICAgICAgICAgICAgdnAtPnZhbC5zdHJpbmcgPSAodV9jaGFyICopIHZwLT5idWY7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICB2cC0+dmFsLnN0cmluZyA9ICh1X2NoYXIgKikgbWFsbG9jKHZwLT52YWxfbGVuKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAodnAtPnZhbC5zdHJpbmcgPT0gTlVMTCkgewogICAgICAgICAgICAgICAgcmV0dXJuIC0xOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGFzbl9wYXJzZV9zdHJpbmcodmFyX3ZhbCwgJmxlbiwgJnZwLT50eXBlLCB2cC0+dmFsLnN0cmluZywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmdnAtPnZhbF9sZW4pOwogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIEFTTl9PQkpFQ1RfSUQ6CiAgICAgICAgICAgIHZwLT52YWxfbGVuID0gTUFYX09JRF9MRU47CiAgICAgICAgICAgIGFzbl9wYXJzZV9vYmppZCh2YXJfdmFsLCAmbGVuLCAmdnAtPnR5cGUsIG9iamlkLCAmdnAtPnZhbF9sZW4pOwogICAgICAgICAgICB2cC0+dmFsX2xlbiAqPSBzaXplb2Yob2lkKTsKICAgICAgICAgICAgdnAtPnZhbC5vYmppZCA9IChvaWQgKikgbWFsbG9jKHZwLT52YWxfbGVuKTsKICAgICAgICAgICAgaWYgKHZwLT52YWwub2JqaWQgPT0gTlVMTCkgewogICAgICAgICAgICAgICAgcmV0dXJuIC0xOwogICAgICAgICAgICB9CiAgICAgICAgICAgIG1lbW1vdmUodnAtPnZhbC5vYmppZCwgb2JqaWQsIHZwLT52YWxfbGVuKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSBTTk1QX05PU1VDSE9CSkVDVDoKICAgICAgICBjYXNlIFNOTVBfTk9TVUNISU5TVEFOQ0U6CiAgICAgICAgY2FzZSBTTk1QX0VORE9GTUlCVklFVzoKICAgICAgICBjYXNlIEFTTl9OVUxMOgogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIEFTTl9CSVRfU1RSOgogICAgICAgICAgICB2cC0+dmFsLmJpdHN0cmluZyA9ICh1X2NoYXIgKikgbWFsbG9jKHZwLT52YWxfbGVuKTsKICAgICAgICAgICAgaWYgKHZwLT52YWwuYml0c3RyaW5nID09IE5VTEwpIHsKICAgICAgICAgICAgICAgIHJldHVybiAtMTsKICAgICAgICAgICAgfQogICAgICAgICAgICBhc25fcGFyc2VfYml0c3RyaW5nKHZhcl92YWwsICZsZW4sICZ2cC0+dHlwZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2cC0+dmFsLmJpdHN0cmluZywgJnZwLT52YWxfbGVuKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgc25tcF9sb2coTE9HX0VSUiwgImJhZCB0eXBlIHJldHVybmVkICgleClcbiIsIHZwLT50eXBlKTsKICAgICAgICAgICAgYmFkdHlwZSA9IC0xOwogICAgICAgICAgICBicmVhazsKICAgICAgICB9CiAgICAgICAgREVCVUdJTkRFTlRBREQoLTQpOwogICAgfQogICAgcmV0dXJuIGJhZHR5cGU7Cn0KCi8qCiAqIHNubXAgdjMgdXRpbGl0eSBmdW5jdGlvbiB0byBwYXJzZSBpbnRvIHRoZSBzY29wZWRQZHUuIHN0b3JlcyBjb250ZXh0TmFtZQogKiBhbmQgY29udGV4dEVuZ2luZUlEIGluIHBkdSBzdHJ1Y3QuIEFsc28gc3RvcmVzIHBkdS0+Y29tbWFuZCAoaGFuZHkgZm9yIAogKiBSZXBvcnQgZ2VuZXJhdGlvbikuCiAqIAogKiByZXR1cm5zIHBvaW50ZXIgdG8gYmVnaW5pbmcgb2YgUERVIG9yIE5VTEwgb24gZXJyb3IuCiAqLwp1X2NoYXIgICAgICAgICAqCnNubXB2M19zY29wZWRQRFVfcGFyc2UobmV0c25tcF9wZHUgKnBkdSwgdV9jaGFyICogY3AsIHNpemVfdCAqIGxlbmd0aCkKewogICAgdV9jaGFyICAgICAgICAgIHRtcF9idWZbU05NUF9NQVhfTVNHX1NJWkVdOwogICAgc2l6ZV90ICAgICAgICAgIHRtcF9idWZfbGVuOwogICAgdV9jaGFyICAgICAgICAgIHR5cGU7CiAgICBzaXplX3QgICAgICAgICAgYXNuX2xlbjsKICAgIHVfY2hhciAgICAgICAgICpkYXRhOwoKICAgIHBkdS0+Y29tbWFuZCA9IDA7ICAgICAgICAgICAvKiBpbml0aWFsaXplIHNvIHdlIGtub3cgaWYgaXQgZ290IHBhcnNlZCAqLwogICAgYXNuX2xlbiA9ICpsZW5ndGg7CiAgICBkYXRhID0gYXNuX3BhcnNlX3NlcXVlbmNlKGNwLCAmYXNuX2xlbiwgJnR5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChBU05fU0VRVUVOQ0UgfCBBU05fQ09OU1RSVUNUT1IpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAicGxhaW50ZXh0IHNjb3BlZFBEVSIpOwogICAgaWYgKGRhdGEgPT0gTlVMTCkgewogICAgICAgIHJldHVybiBOVUxMOwogICAgfQogICAgKmxlbmd0aCAtPSBkYXRhIC0gY3A7CgogICAgLyoKICAgICAqIGNvbnRleHRFbmdpbmVJRCBmcm9tIHNjb3BlZFBkdSAgCiAgICAgKi8KICAgIERFQlVHRFVNUEhFQURFUigicmVjdiIsICJjb250ZXh0RW5naW5lSUQiKTsKICAgIGRhdGEgPSBhc25fcGFyc2Vfc3RyaW5nKGRhdGEsIGxlbmd0aCwgJnR5cGUsIHBkdS0+Y29udGV4dEVuZ2luZUlELAogICAgICAgICAgICAgICAgICAgICAgICAgICAgJnBkdS0+Y29udGV4dEVuZ2luZUlETGVuKTsKICAgIERFQlVHSU5ERU5UTEVTUygpOwogICAgaWYgKGRhdGEgPT0gTlVMTCkgewogICAgICAgIEVSUk9SX01TRygiZXJyb3IgcGFyc2luZyBjb250ZXh0RW5naW5lSUQgZnJvbSBzY29wZWRQZHUiKTsKICAgICAgICByZXR1cm4gTlVMTDsKICAgIH0KCiAgICAvKgogICAgICogY2hlY2sgdGhhdCBpdCBhZ3JlZXMgd2l0aCBlbmdpbmVJRCByZXR1cm5lZCBmcm9tIFVTTSBhYm92ZQogICAgICogKiBvbmx5IGEgd2FybmluZyBiZWNhdXNlIHRoaXMgY291bGQgYmUgbGVnYWwgaWYgd2UgYXJlIGEgcHJveHkKICAgICAqLwogICAgaWYgKHBkdS0+c2VjdXJpdHlFbmdpbmVJRExlbiAhPSBwZHUtPmNvbnRleHRFbmdpbmVJRExlbiB8fAogICAgICAgIG1lbWNtcChwZHUtPnNlY3VyaXR5RW5naW5lSUQsIHBkdS0+Y29udGV4dEVuZ2luZUlELAogICAgICAgICAgICAgICBwZHUtPnNlY3VyaXR5RW5naW5lSURMZW4pICE9IDApIHsKICAgICAgICBERUJVR01TR1RMKCgic2NvcGVkUERVX3BhcnNlIiwKICAgICAgICAgICAgICAgICAgICAiaW5jb25zaXN0ZW50IGVuZ2luZUlEIGluZm9ybWF0aW9uIGluIG1lc3NhZ2VcbiIpKTsKICAgIH0KCiAgICAvKgogICAgICogcGFyc2UgY29udGV4dE5hbWUgZnJvbSBzY29wZWRQZHUKICAgICAqLwogICAgdG1wX2J1Zl9sZW4gPSBTTk1QX01BWF9DT05URVhUX1NJWkU7CiAgICBERUJVR0RVTVBIRUFERVIoInJlY3YiLCAiY29udGV4dE5hbWUiKTsKICAgIGRhdGEgPSBhc25fcGFyc2Vfc3RyaW5nKGRhdGEsIGxlbmd0aCwgJnR5cGUsIHRtcF9idWYsICZ0bXBfYnVmX2xlbik7CiAgICBERUJVR0lOREVOVExFU1MoKTsKICAgIGlmIChkYXRhID09IE5VTEwpIHsKICAgICAgICBFUlJPUl9NU0coImVycm9yIHBhcnNpbmcgY29udGV4dE5hbWUgZnJvbSBzY29wZWRQZHUiKTsKICAgICAgICByZXR1cm4gTlVMTDsKICAgIH0KCiAgICBpZiAodG1wX2J1Zl9sZW4pIHsKICAgICAgICBwZHUtPmNvbnRleHROYW1lID0gKGNoYXIgKikgbWFsbG9jKHRtcF9idWZfbGVuKTsKICAgICAgICBtZW1tb3ZlKHBkdS0+Y29udGV4dE5hbWUsIHRtcF9idWYsIHRtcF9idWZfbGVuKTsKICAgICAgICBwZHUtPmNvbnRleHROYW1lTGVuID0gdG1wX2J1Zl9sZW47CiAgICB9IGVsc2UgewogICAgICAgIHBkdS0+Y29udGV4dE5hbWUgPSBzdHJkdXAoIiIpOwogICAgICAgIHBkdS0+Y29udGV4dE5hbWVMZW4gPSAwOwogICAgfQogICAgaWYgKHBkdS0+Y29udGV4dE5hbWUgPT0gTlVMTCkgewogICAgICAgIEVSUk9SX01TRygiZXJyb3IgY29weWluZyBjb250ZXh0TmFtZSBmcm9tIHNjb3BlZFBkdSIpOwogICAgICAgIHJldHVybiBOVUxMOwogICAgfQoKICAgIC8qCiAgICAgKiBHZXQgdGhlIFBEVSB0eXBlIAogICAgICovCiAgICBhc25fbGVuID0gKmxlbmd0aDsKICAgIGNwID0gYXNuX3BhcnNlX2hlYWRlcihkYXRhLCAmYXNuX2xlbiwgJnR5cGUpOwogICAgaWYgKGNwID09IE5VTEwpCiAgICAgICAgcmV0dXJuIE5VTEw7CgogICAgcGR1LT5jb21tYW5kID0gdHlwZTsKCiAgICByZXR1cm4gZGF0YTsKfQoKLyoKICogVGhlc2UgZnVuY3Rpb25zIHNlbmQgUERVcyB1c2luZyBhbiBhY3RpdmUgc2Vzc2lvbjoKICogc25tcF9zZW5kICAgICAgICAgICAgIC0gdHJhZGl0aW9uYWwgQVBJLCBubyBjYWxsYmFjawogKiBzbm1wX2FzeW5jX3NlbmQgICAgICAgLSB0cmFkaXRpb25hbCBBUEksIHdpdGggY2FsbGJhY2sKICogc25tcF9zZXNzX3NlbmQgICAgICAgIC0gc2luZ2xlIHNlc3Npb24gQVBJLCBubyBjYWxsYmFjawogKiBzbm1wX3Nlc3NfYXN5bmNfc2VuZCAgLSBzaW5nbGUgc2Vzc2lvbiBBUEksIHdpdGggY2FsbGJhY2sKICoKICogQ2FsbCBzbm1wX2J1aWxkIHRvIGNyZWF0ZSBhIHNlcmlhbGl6ZWQgcGFja2V0ICh0aGUgcGR1KS4KICogSWYgbmVjZXNzYXJ5LCBzZXQgc29tZSBvZiB0aGUgcGR1IGRhdGEgZnJvbSB0aGUKICogc2Vzc2lvbiBkZWZhdWx0cy4KICogSWYgdGhlcmUgaXMgYW4gZXhwZWN0ZWQgcmVzcG9uc2UgZm9yIHRoaXMgUERVLAogKiBxdWV1ZSBhIGNvcnJlc3BvbmRpbmcgcmVxdWVzdCBvbiB0aGUgbGlzdAogKiBvZiBvdXRzdGFuZGluZyByZXF1ZXN0cyBmb3IgdGhpcyBzZXNzaW9uLAogKiBhbmQgc3RvcmUgdGhlIGNhbGxiYWNrIHZlY3RvcnMgaW4gdGhlIHJlcXVlc3QuCiAqCiAqIFNlbmQgdGhlIHBkdSB0byB0aGUgdGFyZ2V0IGlkZW50aWZpZWQgYnkgdGhpcyBzZXNzaW9uLgogKiBSZXR1cm4gb24gc3VjY2VzczoKICogICBUaGUgcmVxdWVzdCBpZCBvZiB0aGUgcGR1IGlzIHJldHVybmVkLCBhbmQgdGhlIHBkdSBpcyBmcmVlZC4KICogUmV0dXJuIG9uIGZhaWx1cmU6CiAqICAgWmVybyAoMCkgaXMgcmV0dXJuZWQuCiAqICAgVGhlIGNhbGxlciBtdXN0IGNhbGwgc25tcF9mcmVlX3BkdSBpZiAwIGlzIHJldHVybmVkLgogKi8KaW50CnNubXBfc2VuZChuZXRzbm1wX3Nlc3Npb24gKiBzZXNzaW9uLCBuZXRzbm1wX3BkdSAqcGR1KQp7CiAgICByZXR1cm4gc25tcF9hc3luY19zZW5kKHNlc3Npb24sIHBkdSwgTlVMTCwgTlVMTCk7Cn0KCmludApzbm1wX3Nlc3Nfc2VuZCh2b2lkICpzZXNzcCwgbmV0c25tcF9wZHUgKnBkdSkKewogICAgcmV0dXJuIHNubXBfc2Vzc19hc3luY19zZW5kKHNlc3NwLCBwZHUsIE5VTEwsIE5VTEwpOwp9CgppbnQKc25tcF9hc3luY19zZW5kKG5ldHNubXBfc2Vzc2lvbiAqIHNlc3Npb24sCiAgICAgICAgICAgICAgICBuZXRzbm1wX3BkdSAqcGR1LCBzbm1wX2NhbGxiYWNrIGNhbGxiYWNrLCB2b2lkICpjYl9kYXRhKQp7CiAgICB2b2lkICAgICAgICAgICAqc2Vzc3AgPSBzbm1wX3Nlc3NfcG9pbnRlcihzZXNzaW9uKTsKICAgIHJldHVybiBzbm1wX3Nlc3NfYXN5bmNfc2VuZChzZXNzcCwgcGR1LCBjYWxsYmFjaywgY2JfZGF0YSk7Cn0KCnN0YXRpYyBpbnQKX3Nlc3NfYXN5bmNfc2VuZCh2b2lkICpzZXNzcCwKICAgICAgICAgICAgICAgICBuZXRzbm1wX3BkdSAqcGR1LCBzbm1wX2NhbGxiYWNrIGNhbGxiYWNrLCB2b2lkICpjYl9kYXRhKQp7CiAgICBzdHJ1Y3Qgc2Vzc2lvbl9saXN0ICpzbHAgPSAoc3RydWN0IHNlc3Npb25fbGlzdCAqKSBzZXNzcDsKICAgIG5ldHNubXBfc2Vzc2lvbiAqc2Vzc2lvbjsKICAgIHN0cnVjdCBzbm1wX2ludGVybmFsX3Nlc3Npb24gKmlzcDsKICAgIG5ldHNubXBfdHJhbnNwb3J0ICp0cmFuc3BvcnQgPSBOVUxMOwogICAgdV9jaGFyICAgICAgICAgKnBrdGJ1ZiA9IE5VTEwsICpwYWNrZXQgPSBOVUxMOwogICAgc2l6ZV90ICAgICAgICAgIHBrdGJ1Zl9sZW4gPSAwLCBvZmZzZXQgPSAwLCBsZW5ndGggPSAwOwogICAgaW50ICAgICAgICAgICAgIHJlc3VsdDsKICAgIGxvbmcgICAgICAgICAgICByZXFpZDsKCiAgICBpZiAoc2xwID09IE5VTEwpIHsKICAgICAgICByZXR1cm4gMDsKICAgIH0gZWxzZSB7CiAgICAgICAgc2Vzc2lvbiA9IHNscC0+c2Vzc2lvbjsKICAgICAgICBpc3AgPSBzbHAtPmludGVybmFsOwogICAgICAgIHRyYW5zcG9ydCA9IHNscC0+dHJhbnNwb3J0OwogICAgICAgIGlmICghc2Vzc2lvbiB8fCAhaXNwIHx8ICF0cmFuc3BvcnQpIHsKICAgICAgICAgICAgREVCVUdNU0dUTCgoInNlc3NfYXN5bmNfc2VuZCIsICJzZW5kIGZhaWw6IGNsb3NpbmcuLi5cbiIpKTsKICAgICAgICAgICAgcmV0dXJuIDA7CiAgICAgICAgfQogICAgfQoKICAgIGlmIChwZHUgPT0gTlVMTCkgewogICAgICAgIHNlc3Npb24tPnNfc25tcF9lcnJubyA9IFNOTVBFUlJfTlVMTF9QRFU7CiAgICAgICAgcmV0dXJuIDA7CiAgICB9CgogICAgc2Vzc2lvbi0+c19zbm1wX2Vycm5vID0gMDsKICAgIHNlc3Npb24tPnNfZXJybm8gPSAwOwoKICAgIC8qCiAgICAgKiBDaGVjay9zZXR1cCB0aGUgdmVyc2lvbi4gIAogICAgICovCiAgICBpZiAocGR1LT52ZXJzaW9uID09IFNOTVBfREVGQVVMVF9WRVJTSU9OKSB7CiAgICAgICAgaWYgKHNlc3Npb24tPnZlcnNpb24gPT0gU05NUF9ERUZBVUxUX1ZFUlNJT04pIHsKICAgICAgICAgICAgc2Vzc2lvbi0+c19zbm1wX2Vycm5vID0gU05NUEVSUl9CQURfVkVSU0lPTjsKICAgICAgICAgICAgcmV0dXJuIDA7CiAgICAgICAgfQogICAgICAgIHBkdS0+dmVyc2lvbiA9IHNlc3Npb24tPnZlcnNpb247CiAgICB9IGVsc2UgaWYgKHNlc3Npb24tPnZlcnNpb24gPT0gU05NUF9ERUZBVUxUX1ZFUlNJT04pIHsKICAgICAgICAvKgogICAgICAgICAqIEl0J3MgT0sgIAogICAgICAgICAqLwogICAgfSBlbHNlIGlmIChwZHUtPnZlcnNpb24gIT0gc2Vzc2lvbi0+dmVyc2lvbikgewogICAgICAgIC8qCiAgICAgICAgICogRU5IQU5DRTogd2Ugc2hvdWxkIHN1cHBvcnQgbXVsdGktbGluZ3VhbCBzZXNzaW9ucyAgCiAgICAgICAgICovCiAgICAgICAgc2Vzc2lvbi0+c19zbm1wX2Vycm5vID0gU05NUEVSUl9CQURfVkVSU0lPTjsKICAgICAgICByZXR1cm4gMDsKICAgIH0KCiAgICAvKgogICAgICogZG8gd2UgZXhwZWN0IGEgcmVzcG9uc2U/CiAgICAgKi8KICAgIHN3aXRjaCAocGR1LT5jb21tYW5kKSB7CgogICAgICAgIGNhc2UgU05NUF9NU0dfUkVTUE9OU0U6CiAgICAgICAgY2FzZSBTTk1QX01TR19UUkFQOgogICAgICAgIGNhc2UgU05NUF9NU0dfVFJBUDI6CiAgICAgICAgY2FzZSBTTk1QX01TR19SRVBPUlQ6CiAgICAgICAgY2FzZSBBR0VOVFhfTVNHX0NMRUFOVVBTRVQ6CiAgICAgICAgY2FzZSBBR0VOVFhfTVNHX1JFU1BPTlNFOgogICAgICAgICAgICBwZHUtPmZsYWdzICY9IH5VQ0RfTVNHX0ZMQUdfRVhQRUNUX1JFU1BPTlNFOwogICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgCiAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgcGR1LT5mbGFncyB8PSBVQ0RfTVNHX0ZMQUdfRVhQRUNUX1JFU1BPTlNFOwogICAgICAgICAgICBicmVhazsKICAgIH0KCiAgICAvKgogICAgICogY2hlY2sgdG8gc2VlIGlmIHdlIG5lZWQgYSB2MyBlbmdpbmVJRCBwcm9iZQogICAgICovCiAgICBpZiAoKHBkdS0+dmVyc2lvbiA9PSBTTk1QX1ZFUlNJT05fMykgJiYKICAgICAgICAocGR1LT5mbGFncyAmIFVDRF9NU0dfRkxBR19FWFBFQ1RfUkVTUE9OU0UpICYmCiAgICAgICAgKHNlc3Npb24tPnNlY3VyaXR5RW5naW5lSURMZW4gPT0gMCkgJiYKICAgICAgICAoMCA9PSAoc2Vzc2lvbi0+ZmxhZ3MgJiBTTk1QX0ZMQUdTX0RPTlRfUFJPQkUpKSkgewogICAgICAgIGludCByYzsKICAgICAgICBERUJVR01TR1RMKCgic25tcHYzX2J1aWxkIiwgImRlbGF5ZWQgcHJvYmUgZm9yIGVuZ2luZUlEXG4iKSk7CiAgICAgICAgcmMgPSBzbm1wdjNfZW5naW5lSURfcHJvYmUoc2xwLCBzZXNzaW9uKTsKICAgICAgICBpZiAocmMgPT0gMCkKICAgICAgICAgICAgcmV0dXJuIDA7IC8qIHNfc25tcF9lcnJubyBhbHJlYWR5IHNldCAqLwogICAgfQoKICAgIC8qCiAgICAgKiBjaGVjayB0byBzZWUgaWYgd2UgbmVlZCB0byBjcmVhdGUgYSB2MyB1c2VyIGZyb20gdGhlIHNlc3Npb24gaW5mbwogICAgICovCiAgICBpZiAoY3JlYXRlX3VzZXJfZnJvbV9zZXNzaW9uKHNlc3Npb24pICE9IFNOTVBFUlJfU1VDQ0VTUykgewogICAgICAgIHNlc3Npb24tPnNfc25tcF9lcnJubyA9IFNOTVBFUlJfVU5LTk9XTl9VU0VSX05BTUU7ICAvKiBYWD8/ICovCiAgICAgICAgREVCVUdNU0dUTCgoInNubXBfYXBpIiwKICAgICAgICAgICAgICAgICAgICAic25tcF9zZW5kKCk6IGZhaWxlZCgyKSB0byBjcmVhdGUgYSBuZXcgdXNlciBmcm9tIHNlc3Npb25cbiIpKTsKICAgICAgICByZXR1cm4gMDsKICAgIH0KCiAgICBpZiAoKHBrdGJ1ZiA9ICh1X2NoYXIgKiltYWxsb2MoMjA0OCkpID09IE5VTEwpIHsKICAgICAgICBERUJVR01TR1RMKCgic2Vzc19hc3luY19zZW5kIiwKICAgICAgICAgICAgICAgICAgICAiY291bGRuJ3QgbWFsbG9jIGluaXRpYWwgcGFja2V0IGJ1ZmZlclxuIikpOwogICAgICAgIHNlc3Npb24tPnNfc25tcF9lcnJubyA9IFNOTVBFUlJfTUFMTE9DOwogICAgICAgIHJldHVybiAwOwogICAgfSBlbHNlIHsKICAgICAgICBwa3RidWZfbGVuID0gMjA0ODsKICAgIH0KCiNpZiBURU1QT1JBUklMWV9ESVNBQkxFRAogICAgLyoKICAgICAqICBOVUxMIHZhcmlhYmxlIGFyZSBhbGxvd2VkIGluIGNlcnRhaW4gUERVIHR5cGVzLgogICAgICogIEluIHBhcnRpY3VsYXIsIFNOTVB2MyBlbmdpbmVJRCBwcm9iZXMgYXJlIG9mIHRoaXMgZm9ybS4KICAgICAqICBUaGVyZSBpcyBhbiBpbnRlcm5hbCBQRFUgZmxhZyB0byBpbmRpY2F0ZSB0aGF0IHRoaXMKICAgICAqICAgIGlzIGFjY2VwdGFibGUsIGJ1dCB1bnRpbCB0aGUgY29uc3RydWN0aW9uIG9mIGVuZ2luZUlECiAgICAgKiAgICBwcm9iZXMgY2FuIGJlIGFtZW5kZWQgdG8gc2V0IHRoaXMgZmxhZywgd2UnbGwgc2ltcGx5CiAgICAgKiAgICBza2lwIHRoaXMgdGVzdCBhbHRvZ2V0aGVyLgogICAgICovCiAgICBpZiAocGR1LT52YXJpYWJsZXMgPT0gTlVMTCkgewogICAgICAgIHN3aXRjaCAocGR1LT5jb21tYW5kKSB7CiAgICAgICAgY2FzZSBTTk1QX01TR19HRVQ6CiAgICAgICAgY2FzZSBTTk1QX01TR19TRVQ6CiAgICAgICAgY2FzZSBTTk1QX01TR19HRVRORVhUOgogICAgICAgIGNhc2UgU05NUF9NU0dfR0VUQlVMSzoKICAgICAgICBjYXNlIFNOTVBfTVNHX1JFU1BPTlNFOgogICAgICAgIGNhc2UgU05NUF9NU0dfVFJBUDI6CiAgICAgICAgY2FzZSBTTk1QX01TR19SRVBPUlQ6CiAgICAgICAgY2FzZSBTTk1QX01TR19JTkZPUk06CiAgICAgICAgICAgIHNlc3Npb24tPnNfc25tcF9lcnJubyA9IHNubXBfZXJybm8gPSBTTk1QRVJSX05PX1ZBUlM7CiAgICAgICAgICAgIHJldHVybiAwOwogICAgICAgIGNhc2UgU05NUF9NU0dfVFJBUDoKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgfQogICAgfQojZW5kaWYKCgogICAgLyoKICAgICAqIEJ1aWxkIHRoZSBtZXNzYWdlIHRvIHNlbmQuICAKICAgICAqLwogICAgaWYgKGlzcC0+aG9va19yZWFsbG9jX2J1aWxkKSB7CiAgICAgICAgcmVzdWx0ID0gaXNwLT5ob29rX3JlYWxsb2NfYnVpbGQoc2Vzc2lvbiwgcGR1LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZwa3RidWYsICZwa3RidWZfbGVuLCAmb2Zmc2V0KTsKICAgICAgICBwYWNrZXQgPSBwa3RidWY7CiAgICAgICAgbGVuZ3RoID0gb2Zmc2V0OwogICAgfSBlbHNlIGlmIChpc3AtPmhvb2tfYnVpbGQpIHsKICAgICAgICBwYWNrZXQgPSBwa3RidWY7CiAgICAgICAgbGVuZ3RoID0gcGt0YnVmX2xlbjsKICAgICAgICByZXN1bHQgPSBpc3AtPmhvb2tfYnVpbGQoc2Vzc2lvbiwgcGR1LCBwa3RidWYsICZsZW5ndGgpOwogICAgfSBlbHNlIHsKI2lmZGVmIE5FVFNOTVBfVVNFX1JFVkVSU0VfQVNORU5DT0RJTkcKICAgICAgICBpZiAobmV0c25tcF9kc19nZXRfYm9vbGVhbihORVRTTk1QX0RTX0xJQlJBUllfSUQsIE5FVFNOTVBfRFNfTElCX1JFVkVSU0VfRU5DT0RFKSkgewogICAgICAgICAgICByZXN1bHQgPQogICAgICAgICAgICAgICAgc25tcF9idWlsZCgmcGt0YnVmLCAmcGt0YnVmX2xlbiwgJm9mZnNldCwgc2Vzc2lvbiwgcGR1KTsKICAgICAgICAgICAgcGFja2V0ID0gcGt0YnVmICsgcGt0YnVmX2xlbiAtIG9mZnNldDsKICAgICAgICAgICAgbGVuZ3RoID0gb2Zmc2V0OwogICAgICAgIH0gZWxzZSB7CiNlbmRpZgogICAgICAgICAgICBwYWNrZXQgPSBwa3RidWY7CiAgICAgICAgICAgIGxlbmd0aCA9IHBrdGJ1Zl9sZW47CiAgICAgICAgICAgIHJlc3VsdCA9IHNubXBfYnVpbGQoJnBrdGJ1ZiwgJmxlbmd0aCwgJm9mZnNldCwgc2Vzc2lvbiwgcGR1KTsKI2lmZGVmIE5FVFNOTVBfVVNFX1JFVkVSU0VfQVNORU5DT0RJTkcKICAgICAgICB9CiNlbmRpZgogICAgfQoKICAgIGlmIChyZXN1bHQgPCAwKSB7CiAgICAgICAgREVCVUdNU0dUTCgoInNlc3NfYXN5bmNfc2VuZCIsICJlbmNvZGluZyBmYWlsdXJlXG4iKSk7CiAgICAgICAgU05NUF9GUkVFKHBrdGJ1Zik7CiAgICAgICAgcmV0dXJuIDA7CiAgICB9CgogICAgLyoKICAgICAqIE1ha2Ugc3VyZSB3ZSBkb24ndCBzZW5kIHNvbWV0aGluZyB0aGF0IGlzIGJpZ2dlciB0aGFuIHRoZSBtc2dNYXhTaXplCiAgICAgKiBzcGVjaWZpZWQgaW4gdGhlIHJlY2VpdmVkIFBEVS4gIAogICAgICovCgogICAgaWYgKHNlc3Npb24tPnNuZE1zZ01heFNpemUgIT0gMCAmJiBsZW5ndGggPiBzZXNzaW9uLT5zbmRNc2dNYXhTaXplKSB7CiAgICAgICAgREVCVUdNU0dUTCgoInNlc3NfYXN5bmNfc2VuZCIsCiAgICAgICAgICAgICAgICAgICAgImxlbmd0aCBvZiBwYWNrZXQgKCVsdSkgZXhjZWVkcyBzZXNzaW9uIG1heGltdW0gKCVsdSlcbiIsCiAgICAgICAgICAgICAgICAgICAgbGVuZ3RoLCBzZXNzaW9uLT5zbmRNc2dNYXhTaXplKSk7CiAgICAgICAgc2Vzc2lvbi0+c19zbm1wX2Vycm5vID0gU05NUEVSUl9UT09fTE9ORzsKICAgICAgICBTTk1QX0ZSRUUocGt0YnVmKTsKICAgICAgICByZXR1cm4gMDsKICAgIH0KCiAgICAvKgogICAgICogQ2hlY2sgdGhhdCB0aGUgdW5kZXJseWluZyB0cmFuc3BvcnQgaXMgY2FwYWJsZSBvZiBzZW5kaW5nIGEgcGFja2V0IGFzCiAgICAgKiBsYXJnZSBhcyBsZW5ndGguICAKICAgICAqLwoKICAgIGlmICh0cmFuc3BvcnQtPm1zZ01heFNpemUgIT0gMCAmJiBsZW5ndGggPiB0cmFuc3BvcnQtPm1zZ01heFNpemUpIHsKICAgICAgICBERUJVR01TR1RMKCgic2Vzc19hc3luY19zZW5kIiwKICAgICAgICAgICAgICAgICAgICAibGVuZ3RoIG9mIHBhY2tldCAoJWx1KSBleGNlZWRzIHRyYW5zcG9ydCBtYXhpbXVtICglbHUpXG4iLAogICAgICAgICAgICAgICAgICAgIGxlbmd0aCwgdHJhbnNwb3J0LT5tc2dNYXhTaXplKSk7CiAgICAgICAgc2Vzc2lvbi0+c19zbm1wX2Vycm5vID0gU05NUEVSUl9UT09fTE9ORzsKICAgICAgICBTTk1QX0ZSRUUocGt0YnVmKTsKICAgICAgICByZXR1cm4gMDsKICAgIH0KCiAgICBpZiAobmV0c25tcF9kc19nZXRfYm9vbGVhbihORVRTTk1QX0RTX0xJQlJBUllfSUQsIE5FVFNOTVBfRFNfTElCX0RVTVBfUEFDS0VUKSkgewogICAgICAgIGlmICh0cmFuc3BvcnQtPmZfZm10YWRkciAhPSBOVUxMKSB7CiAgICAgICAgICAgIGNoYXIgICAgICAgICAgICpkZXN0X3R4dCA9CiAgICAgICAgICAgICAgICB0cmFuc3BvcnQtPmZfZm10YWRkcih0cmFuc3BvcnQsIHBkdS0+dHJhbnNwb3J0X2RhdGEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwZHUtPnRyYW5zcG9ydF9kYXRhX2xlbmd0aCk7CiAgICAgICAgICAgIGlmIChkZXN0X3R4dCAhPSBOVUxMKSB7CiAgICAgICAgICAgICAgICBzbm1wX2xvZyhMT0dfREVCVUcsICJcblNlbmRpbmcgJWx1IGJ5dGVzIHRvICVzXG4iLCAodW5zaWduZWQgbG9uZylsZW5ndGgsCiAgICAgICAgICAgICAgICAgICAgICAgICBkZXN0X3R4dCk7CiAgICAgICAgICAgICAgICBTTk1QX0ZSRUUoZGVzdF90eHQpOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgc25tcF9sb2coTE9HX0RFQlVHLCAiXG5TZW5kaW5nICVsdSBieXRlcyB0byA8VU5LTk9XTj5cbiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAodW5zaWduZWQgbG9uZylsZW5ndGgpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHhkdW1wKHBhY2tldCwgbGVuZ3RoLCAiIik7CiAgICB9CgogICAgLyoKICAgICAqIFNlbmQgdGhlIG1lc3NhZ2UuICAKICAgICAqLwoKICAgIHJlc3VsdCA9IHRyYW5zcG9ydC0+Zl9zZW5kKHRyYW5zcG9ydCwgcGFja2V0LCBsZW5ndGgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmKHBkdS0+dHJhbnNwb3J0X2RhdGEpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJihwZHUtPnRyYW5zcG9ydF9kYXRhX2xlbmd0aCkpOwoKICAgIFNOTVBfRlJFRShwa3RidWYpOwoKICAgIGlmIChyZXN1bHQgPCAwKSB7CiAgICAgICAgc2Vzc2lvbi0+c19zbm1wX2Vycm5vID0gU05NUEVSUl9CQURfU0VORFRPOwogICAgICAgIHNlc3Npb24tPnNfZXJybm8gPSBlcnJubzsKICAgICAgICByZXR1cm4gMDsKICAgIH0KCiAgICByZXFpZCA9IHBkdS0+cmVxaWQ7CgogICAgLyoKICAgICAqIEFkZCB0byBwZW5kaW5nIHJlcXVlc3RzIGxpc3QgaWYgd2UgZXhwZWN0IGEgcmVzcG9uc2UuICAKICAgICAqLwogICAgaWYgKHBkdS0+ZmxhZ3MgJiBVQ0RfTVNHX0ZMQUdfRVhQRUNUX1JFU1BPTlNFKSB7CiAgICAgICAgbmV0c25tcF9yZXF1ZXN0X2xpc3QgKnJwOwogICAgICAgIHN0cnVjdCB0aW1ldmFsICB0djsKCiAgICAgICAgcnAgPSAobmV0c25tcF9yZXF1ZXN0X2xpc3QgKikgY2FsbG9jKDEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNpemVvZihuZXRzbm1wX3JlcXVlc3RfbGlzdCkpOwogICAgICAgIGlmIChycCA9PSBOVUxMKSB7CiAgICAgICAgICAgIHNlc3Npb24tPnNfc25tcF9lcnJubyA9IFNOTVBFUlJfR0VORVJSOwogICAgICAgICAgICByZXR1cm4gMDsKICAgICAgICB9CgogICAgICAgIGdldHRpbWVvZmRheSgmdHYsIChzdHJ1Y3QgdGltZXpvbmUgKikgMCk7CiAgICAgICAgcnAtPnBkdSA9IHBkdTsKICAgICAgICBycC0+cmVxdWVzdF9pZCA9IHBkdS0+cmVxaWQ7CiAgICAgICAgcnAtPm1lc3NhZ2VfaWQgPSBwZHUtPm1zZ2lkOwogICAgICAgIHJwLT5jYWxsYmFjayA9IGNhbGxiYWNrOwogICAgICAgIHJwLT5jYl9kYXRhID0gY2JfZGF0YTsKICAgICAgICBycC0+cmV0cmllcyA9IDA7CiAgICAgICAgaWYgKHBkdS0+ZmxhZ3MgJiBVQ0RfTVNHX0ZMQUdfUERVX1RJTUVPVVQpIHsKICAgICAgICAgICAgcnAtPnRpbWVvdXQgPSBwZHUtPnRpbWUgKiAxMDAwMDAwTDsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBycC0+dGltZW91dCA9IHNlc3Npb24tPnRpbWVvdXQ7CiAgICAgICAgfQogICAgICAgIHJwLT50aW1lID0gdHY7CiAgICAgICAgdHYudHZfdXNlYyArPSBycC0+dGltZW91dDsKICAgICAgICB0di50dl9zZWMgKz0gdHYudHZfdXNlYyAvIDEwMDAwMDBMOwogICAgICAgIHR2LnR2X3VzZWMgJT0gMTAwMDAwMEw7CiAgICAgICAgcnAtPmV4cGlyZSA9IHR2OwoKICAgICAgICAvKgogICAgICAgICAqIFhYIGxvY2sgc2hvdWxkIGJlIHBlciBzZXNzaW9uICEgCiAgICAgICAgICovCiAgICAgICAgc25tcF9yZXNfbG9jayhNVF9MSUJSQVJZX0lELCBNVF9MSUJfU0VTU0lPTik7CiAgICAgICAgaWYgKGlzcC0+cmVxdWVzdHNFbmQpIHsKICAgICAgICAgICAgcnAtPm5leHRfcmVxdWVzdCA9IGlzcC0+cmVxdWVzdHNFbmQtPm5leHRfcmVxdWVzdDsKICAgICAgICAgICAgaXNwLT5yZXF1ZXN0c0VuZC0+bmV4dF9yZXF1ZXN0ID0gcnA7CiAgICAgICAgICAgIGlzcC0+cmVxdWVzdHNFbmQgPSBycDsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBycC0+bmV4dF9yZXF1ZXN0ID0gaXNwLT5yZXF1ZXN0czsKICAgICAgICAgICAgaXNwLT5yZXF1ZXN0cyA9IHJwOwogICAgICAgICAgICBpc3AtPnJlcXVlc3RzRW5kID0gcnA7CiAgICAgICAgfQogICAgICAgIHNubXBfcmVzX3VubG9jayhNVF9MSUJSQVJZX0lELCBNVF9MSUJfU0VTU0lPTik7CiAgICB9IGVsc2UgewogICAgICAgIC8qCiAgICAgICAgICogTm8gcmVzcG9uc2UgZXhwZWN0ZWQuLi4gIAogICAgICAgICAqLwogICAgICAgIGlmIChyZXFpZCkgewogICAgICAgICAgICAvKgogICAgICAgICAgICAgKiBGcmVlIHYxIG9yIHYyIFRSQVAgUERVIGlmZiBubyBlcnJvciAgCiAgICAgICAgICAgICAqLwogICAgICAgICAgICBzbm1wX2ZyZWVfcGR1KHBkdSk7CiAgICAgICAgfQogICAgfQoKICAgIHJldHVybiByZXFpZDsKfQoKaW50CnNubXBfc2Vzc19hc3luY19zZW5kKHZvaWQgKnNlc3NwLAogICAgICAgICAgICAgICAgICAgICBuZXRzbm1wX3BkdSAqcGR1LAogICAgICAgICAgICAgICAgICAgICBzbm1wX2NhbGxiYWNrIGNhbGxiYWNrLCB2b2lkICpjYl9kYXRhKQp7CiAgICBpbnQgICAgICAgICAgICAgcmM7CgogICAgaWYgKHNlc3NwID09IE5VTEwpIHsKICAgICAgICBzbm1wX2Vycm5vID0gU05NUEVSUl9CQURfU0VTU0lPTjsgICAgICAgLypNVENSSVRJQ0FMX1JFU09VUkNFICovCiAgICAgICAgcmV0dXJuICgwKTsKICAgIH0KICAgIC8qCiAgICAgKiBzZW5kIHBkdQogICAgICovCiAgICByYyA9IF9zZXNzX2FzeW5jX3NlbmQoc2Vzc3AsIHBkdSwgY2FsbGJhY2ssIGNiX2RhdGEpOwogICAgaWYgKHJjID09IDApIHsKICAgICAgICBzdHJ1Y3Qgc2Vzc2lvbl9saXN0ICpwc2w7CiAgICAgICAgbmV0c25tcF9zZXNzaW9uICpwc3M7CiAgICAgICAgcHNsID0gKHN0cnVjdCBzZXNzaW9uX2xpc3QgKikgc2Vzc3A7CiAgICAgICAgcHNzID0gcHNsLT5zZXNzaW9uOwogICAgICAgIFNFVF9TTk1QX0VSUk9SKHBzcy0+c19zbm1wX2Vycm5vKTsKICAgIH0KICAgIHJldHVybiByYzsKfQoKCi8qCiAqIEZyZWVzIHRoZSB2YXJpYWJsZSBhbmQgYW55IG1hbGxvYydkIGRhdGEgYXNzb2NpYXRlZCB3aXRoIGl0LgogKi8Kdm9pZApzbm1wX2ZyZWVfdmFyKG5ldHNubXBfdmFyaWFibGVfbGlzdCAqIHZhcikKewogICAgaWYgKCF2YXIpCiAgICAgICAgcmV0dXJuOwoKICAgIGlmICh2YXItPm5hbWUgIT0gdmFyLT5uYW1lX2xvYykKICAgICAgICBTTk1QX0ZSRUUodmFyLT5uYW1lKTsKICAgIGlmICh2YXItPnZhbC5zdHJpbmcgIT0gdmFyLT5idWYpCiAgICAgICAgU05NUF9GUkVFKHZhci0+dmFsLnN0cmluZyk7CiAgICBpZiAodmFyLT5kYXRhKSB7CiAgICAgICAgaWYgKHZhci0+ZGF0YUZyZWVIb29rKSB7CiAgICAgICAgICAgIHZhci0+ZGF0YUZyZWVIb29rKHZhci0+ZGF0YSk7CiAgICAgICAgICAgIHZhci0+ZGF0YSA9IE5VTEw7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgU05NUF9GUkVFKHZhci0+ZGF0YSk7CiAgICAgICAgfQogICAgfQoKICAgIGZyZWUoKGNoYXIgKikgdmFyKTsKfQoKdm9pZApzbm1wX2ZyZWVfdmFyYmluZChuZXRzbm1wX3ZhcmlhYmxlX2xpc3QgKiB2YXIpCnsKICAgIG5ldHNubXBfdmFyaWFibGVfbGlzdCAqcHRyOwogICAgd2hpbGUgKHZhcikgewogICAgICAgIHB0ciA9IHZhci0+bmV4dF92YXJpYWJsZTsKICAgICAgICBzbm1wX2ZyZWVfdmFyKHZhcik7CiAgICAgICAgdmFyID0gcHRyOwogICAgfQp9CgovKgogKiBGcmVlcyB0aGUgcGR1IGFuZCBhbnkgbWFsbG9jJ2QgZGF0YSBhc3NvY2lhdGVkIHdpdGggaXQuCiAqLwp2b2lkCnNubXBfZnJlZV9wZHUobmV0c25tcF9wZHUgKnBkdSkKewogICAgc3RydWN0IHNubXBfc2VjbW9kX2RlZiAqc3B0cjsKCiAgICBpZiAoIXBkdSkKICAgICAgICByZXR1cm47CgogICAgLyoKICAgICAqIElmIHRoZSBjb21tYW5kIGZpZWxkIGlzIGVtcHR5LCB0aGF0IHByb2JhYmx5IGluZGljYXRlcwogICAgICogICB0aGF0IHRoaXMgUERVIHN0cnVjdHVyZSBoYXMgYWxyZWFkeSBiZWVuIGZyZWVkLgogICAgICogICBMb2cgYSB3YXJuaW5nIGFuZCByZXR1cm4gKHJhdGhlciB0aGFuIGZyZWVpbmcgdGhpbmdzIGFnYWluKQogICAgICoKICAgICAqIE5vdGUgdGhhdCB0aGlzIGRvZXMgbm90IHBpY2sgdXAgZHVhbC1mcmVlcyB3aGVyZSB0aGUKICAgICAqICAgbWVtb3J5IGlzIHNldCB0byByYW5kb20ganVuaywgd2hpY2ggaXMgcHJvYmFibHkgbW9yZSBzZXJpb3VzLgogICAgICoKICAgICAqIHJrczogd2hpbGUgdGhpcyBpcyBhIGdvb2QgaWRlYSwgdGhlcmUgYXJlIHR3byBwcm9ibGVtcy4KICAgICAqICAgICAgICAgMSkgYWdlbnR4IHNldHMgY29tbWFuZCB0byAwIGluIHNvbWUgY2FzZXMKICAgICAqICAgICAgICAgMikgYWNjb3JkaW5nIHRvIFdlcywgYSBiYWQgZGVjb2RlIG9mIGEgdjMgbWVzc2FnZSBjb3VsZAogICAgICogICAgICAgICAgICByZXN1bHQgaW4gYSAwIGF0IHRoaXMgb2Zmc2V0LgogICAgICogICAgICBzbyBJJ20gY29tbWVudGluZyBpdCBvdXQgdW50aWwgYSBiZXR0ZXIgc29sdXRpb24gaXMgZm91bmQuCiAgICAgKiAgICAgIG5vdGUgdGhhdCBJJ20gbGVhdmluZyB0aGUgbWVtc2V0LCBiZWxvdy4uLi4KICAgICAqCiAgICBpZiAocGR1LT5jb21tYW5kID09IDApIHsKICAgICAgICBzbm1wX2xvZyhMT0dfV0FSTklORywgInNubXBfZnJlZV9wZHUgcHJvYmFibHkgY2FsbGVkIHR3aWNlXG4iKTsKICAgICAgICByZXR1cm47CiAgICB9CiAgICAgKi8KICAgIGlmICgoc3B0ciA9IGZpbmRfc2VjX21vZChwZHUtPnNlY3VyaXR5TW9kZWwpKSAhPSBOVUxMICYmCiAgICAgICAgc3B0ci0+cGR1X2ZyZWUgIT0gTlVMTCkgewogICAgICAgICgqc3B0ci0+cGR1X2ZyZWUpIChwZHUpOwogICAgfQogICAgc25tcF9mcmVlX3ZhcmJpbmQocGR1LT52YXJpYWJsZXMpOwogICAgU05NUF9GUkVFKHBkdS0+ZW50ZXJwcmlzZSk7CiAgICBTTk1QX0ZSRUUocGR1LT5jb21tdW5pdHkpOwogICAgU05NUF9GUkVFKHBkdS0+Y29udGV4dEVuZ2luZUlEKTsKICAgIFNOTVBfRlJFRShwZHUtPnNlY3VyaXR5RW5naW5lSUQpOwogICAgU05NUF9GUkVFKHBkdS0+Y29udGV4dE5hbWUpOwogICAgU05NUF9GUkVFKHBkdS0+c2VjdXJpdHlOYW1lKTsKICAgIFNOTVBfRlJFRShwZHUtPnRyYW5zcG9ydF9kYXRhKTsKICAgIG1lbXNldChwZHUsIDAsIHNpemVvZihuZXRzbm1wX3BkdSkpOwogICAgZnJlZSgoY2hhciAqKSBwZHUpOwp9CgpuZXRzbm1wX3BkdSAgICAqCnNubXBfY3JlYXRlX3Nlc3NfcGR1KG5ldHNubXBfdHJhbnNwb3J0ICp0cmFuc3BvcnQsIHZvaWQgKm9wYXF1ZSwKICAgICAgICAgICAgICAgICAgICAgc2l6ZV90IG9sZW5ndGgpCnsKICAgIG5ldHNubXBfcGR1ICpwZHUgPSAobmV0c25tcF9wZHUgKiljYWxsb2MoMSwgc2l6ZW9mKG5ldHNubXBfcGR1KSk7CiAgICBpZiAocGR1ID09IE5VTEwpIHsKICAgICAgICBERUJVR01TR1RMKCgic2Vzc19wcm9jZXNzX3BhY2tldCIsICJjYW4ndCBtYWxsb2Mgc3BhY2UgZm9yIFBEVVxuIikpOwogICAgICAgIHJldHVybiBOVUxMOwogICAgfQoKICAgIC8qCiAgICAgKiBTYXZlIHRoZSB0cmFuc3BvcnQtbGV2ZWwgZGF0YSBzcGVjaWZpYyB0byB0aGlzIHJlY2VwdGlvbiAoZS5nLiBVRFAKICAgICAqIHNvdXJjZSBhZGRyZXNzKS4gIAogICAgICovCgogICAgcGR1LT50cmFuc3BvcnRfZGF0YSA9IG9wYXF1ZTsKICAgIHBkdS0+dHJhbnNwb3J0X2RhdGFfbGVuZ3RoID0gb2xlbmd0aDsKICAgIHBkdS0+dERvbWFpbiA9IHRyYW5zcG9ydC0+ZG9tYWluOwogICAgcGR1LT50RG9tYWluTGVuID0gdHJhbnNwb3J0LT5kb21haW5fbGVuZ3RoOwogICAgcmV0dXJuIHBkdTsKfQoKCi8qCiAqIFRoaXMgZnVuY3Rpb24gcHJvY2Vzc2VzIGEgY29tcGxldGUgKGFjY29yZGluZyB0byBhc25fY2hlY2tfcGFja2V0IG9yIHRoZQogKiBBZ2VudFggZXF1aXZhbGVudCkgcGFja2V0LCBwYXJzaW5nIGl0IGludG8gYSBQRFUgYW5kIGNhbGxpbmcgdGhlIHJlbGV2YW50CiAqIGNhbGxiYWNrcy4gIE9uIGVudHJ5LCBwYWNrZXRwdHIgcG9pbnRzIGF0IHRoZSBwYWNrZXQgaW4gdGhlIHNlc3Npb24ncwogKiBidWZmZXIgYW5kIGxlbmd0aCBpcyB0aGUgbGVuZ3RoIG9mIHRoZSBwYWNrZXQuICAKICovCgpzdGF0aWMgaW50Cl9zZXNzX3Byb2Nlc3NfcGFja2V0KHZvaWQgKnNlc3NwLCBuZXRzbm1wX3Nlc3Npb24gKiBzcCwKICAgICAgICAgICAgICAgICAgICAgc3RydWN0IHNubXBfaW50ZXJuYWxfc2Vzc2lvbiAqaXNwLAogICAgICAgICAgICAgICAgICAgICBuZXRzbm1wX3RyYW5zcG9ydCAqdHJhbnNwb3J0LAogICAgICAgICAgICAgICAgICAgICB2b2lkICpvcGFxdWUsIGludCBvbGVuZ3RoLAogICAgICAgICAgICAgICAgICAgICB1X2NoYXIgKiBwYWNrZXRwdHIsIGludCBsZW5ndGgpCnsKICBzdHJ1Y3Qgc2Vzc2lvbl9saXN0ICpzbHAgPSAoc3RydWN0IHNlc3Npb25fbGlzdCAqKSBzZXNzcDsKICBuZXRzbm1wX3BkdSAgICAqcGR1OwogIG5ldHNubXBfcmVxdWVzdF9saXN0ICpycCwgKm9ycCA9IE5VTEw7CiAgc3RydWN0IHNubXBfc2VjbW9kX2RlZiAqc3B0cjsKICBpbnQgICAgICAgICAgICAgcmV0ID0gMCwgaGFuZGxlZCA9IDA7CgogIERFQlVHTVNHVEwoKCJzZXNzX3Byb2Nlc3NfcGFja2V0IiwKCSAgICAgICJzZXNzaW9uICVwIGZkICVkIHBrdCAlcCBsZW5ndGggJWRcbiIsIHNlc3NwLAoJICAgICAgdHJhbnNwb3J0LT5zb2NrLCBwYWNrZXRwdHIsIGxlbmd0aCkpOwoKICBpZiAobmV0c25tcF9kc19nZXRfYm9vbGVhbihORVRTTk1QX0RTX0xJQlJBUllfSUQsIAoJCQkgICAgIE5FVFNOTVBfRFNfTElCX0RVTVBfUEFDS0VUKSkgewogICAgaWYgKHRyYW5zcG9ydC0+Zl9mbXRhZGRyICE9IE5VTEwpIHsKICAgICAgY2hhciAqYWRkcnR4dCA9IHRyYW5zcG9ydC0+Zl9mbXRhZGRyKHRyYW5zcG9ydCwgb3BhcXVlLCBvbGVuZ3RoKTsKICAgICAgaWYgKGFkZHJ0eHQgIT0gTlVMTCkgewoJc25tcF9sb2coTE9HX0RFQlVHLCAiXG5SZWNlaXZlZCAlZCBieXRlcyBmcm9tICVzXG4iLAoJCSBsZW5ndGgsIGFkZHJ0eHQpOwoJU05NUF9GUkVFKGFkZHJ0eHQpOwogICAgICB9IGVsc2UgewoJc25tcF9sb2coTE9HX0RFQlVHLCAiXG5SZWNlaXZlZCAlZCBieXRlcyBmcm9tIDxVTktOT1dOPlxuIiwKCQkgbGVuZ3RoKTsKICAgICAgfQogICAgfQogICAgeGR1bXAocGFja2V0cHRyLCBsZW5ndGgsICIiKTsKICB9CgogIC8qCiAgICogRG8gdHJhbnNwb3J0LWxldmVsIGZpbHRlcmluZyAoZS5nLiBJUC1hZGRyZXNzIGJhc2VkIGFsbG93L2RlbnkpLiAgCiAgICovCgogIGlmIChpc3AtPmhvb2tfcHJlKSB7CiAgICBpZiAoaXNwLT5ob29rX3ByZShzcCwgdHJhbnNwb3J0LCBvcGFxdWUsIG9sZW5ndGgpID09IDApIHsKICAgICAgREVCVUdNU0dUTCgoInNlc3NfcHJvY2Vzc19wYWNrZXQiLCAicHJlLXBhcnNlIGZhaWxcbiIpKTsKICAgICAgaWYgKG9wYXF1ZSAhPSBOVUxMKSB7CglTTk1QX0ZSRUUob3BhcXVlKTsKICAgICAgfQogICAgICByZXR1cm4gLTE7CiAgICB9CiAgfQoKICBpZiAoaXNwLT5ob29rX2NyZWF0ZV9wZHUpIHsKICAgIHBkdSA9IGlzcC0+aG9va19jcmVhdGVfcGR1KHRyYW5zcG9ydCwgb3BhcXVlLCBvbGVuZ3RoKTsKICB9IGVsc2UgewogICAgcGR1ID0gc25tcF9jcmVhdGVfc2Vzc19wZHUodHJhbnNwb3J0LCBvcGFxdWUsIG9sZW5ndGgpOwogIH0KICBpZiAocGR1ID09IE5VTEwpIHsKICAgIHNubXBfbG9nKExPR19FUlIsICJwZHUgZmFpbGVkIHRvIGJlIGNyZWF0ZWRcbiIpOwogICAgaWYgKG9wYXF1ZSAhPSBOVUxMKSB7CiAgICAgIFNOTVBfRlJFRShvcGFxdWUpOwogICAgfQogICAgcmV0dXJuIC0xOwogIH0KCiAgaWYgKGlzcC0+aG9va19wYXJzZSkgewogICAgcmV0ID0gaXNwLT5ob29rX3BhcnNlKHNwLCBwZHUsIHBhY2tldHB0ciwgbGVuZ3RoKTsKICB9IGVsc2UgewogICAgcmV0ID0gc25tcF9wYXJzZShzZXNzcCwgc3AsIHBkdSwgcGFja2V0cHRyLCBsZW5ndGgpOwogIH0KCiAgaWYgKHJldCAhPSBTTk1QX0VSUl9OT0VSUk9SKSB7CiAgICBERUJVR01TR1RMKCgic2Vzc19wcm9jZXNzX3BhY2tldCIsICJwYXJzZSBmYWlsXG4iKSk7CiAgfQoKICBpZiAoaXNwLT5ob29rX3Bvc3QpIHsKICAgIGlmIChpc3AtPmhvb2tfcG9zdChzcCwgcGR1LCByZXQpID09IDApIHsKICAgICAgREVCVUdNU0dUTCgoInNlc3NfcHJvY2Vzc19wYWNrZXQiLCAicG9zdC1wYXJzZSBmYWlsXG4iKSk7CiAgICAgIHJldCA9IFNOTVBFUlJfQVNOX1BBUlNFX0VSUjsKICAgIH0KICB9CgogIGlmIChyZXQgIT0gU05NUF9FUlJfTk9FUlJPUikgewogICAgLyoKICAgICAqIENhbGwgdGhlIHNlY3VyaXR5IG1vZGVsIHRvIGZyZWUgYW55IHNlY3VyaXR5U3RhdGVSZWYgc3VwcGxpZWQgdy8gbXNnLiAgCiAgICAgKi8KICAgIGlmIChwZHUtPnNlY3VyaXR5U3RhdGVSZWYgIT0gTlVMTCkgewogICAgICBzcHRyID0gZmluZF9zZWNfbW9kKHBkdS0+c2VjdXJpdHlNb2RlbCk7CiAgICAgIGlmIChzcHRyICE9IE5VTEwpIHsKCWlmIChzcHRyLT5wZHVfZnJlZV9zdGF0ZV9yZWYgIT0gTlVMTCkgewoJICAoKnNwdHItPnBkdV9mcmVlX3N0YXRlX3JlZikgKHBkdS0+c2VjdXJpdHlTdGF0ZVJlZik7Cgl9IGVsc2UgewoJICBzbm1wX2xvZyhMT0dfRVJSLAoJCSAgICJTZWN1cml0eSBNb2RlbCAlZCBjYW4ndCBmcmVlIHN0YXRlIHJlZmVyZW5jZXNcbiIsCgkJICAgcGR1LT5zZWN1cml0eU1vZGVsKTsKCX0KICAgICAgfSBlbHNlIHsKCXNubXBfbG9nKExPR19FUlIsCgkJICJDYW4ndCBmaW5kIHNlY3VyaXR5IG1vZGVsIHRvIGZyZWUgcHRyOiAlZFxuIiwKCQkgcGR1LT5zZWN1cml0eU1vZGVsKTsKICAgICAgfQogICAgICBwZHUtPnNlY3VyaXR5U3RhdGVSZWYgPSBOVUxMOwogICAgfQogICAgc25tcF9mcmVlX3BkdShwZHUpOwogICAgcmV0dXJuIC0xOwogIH0KCiAgaWYgKHBkdS0+ZmxhZ3MgJiBVQ0RfTVNHX0ZMQUdfUkVTUE9OU0VfUERVKSB7CiAgICAvKgogICAgICogQ2FsbCBVU00gdG8gZnJlZSBhbnkgc2VjdXJpdHlTdGF0ZVJlZiBzdXBwbGllZCB3aXRoIHRoZSBtZXNzYWdlLiAgCiAgICAgKi8KICAgIGlmIChwZHUtPnNlY3VyaXR5U3RhdGVSZWYpIHsKICAgICAgc3B0ciA9IGZpbmRfc2VjX21vZChwZHUtPnNlY3VyaXR5TW9kZWwpOwogICAgICBpZiAoc3B0cikgewoJaWYgKHNwdHItPnBkdV9mcmVlX3N0YXRlX3JlZikgewoJICAoKnNwdHItPnBkdV9mcmVlX3N0YXRlX3JlZikgKHBkdS0+c2VjdXJpdHlTdGF0ZVJlZik7Cgl9IGVsc2UgewoJICBzbm1wX2xvZyhMT0dfRVJSLAoJCSAgICJTZWN1cml0eSBNb2RlbCAlZCBjYW4ndCBmcmVlIHN0YXRlIHJlZmVyZW5jZXNcbiIsCgkJICAgcGR1LT5zZWN1cml0eU1vZGVsKTsKCX0KICAgICAgfSBlbHNlIHsKCXNubXBfbG9nKExPR19FUlIsCgkJICJDYW4ndCBmaW5kIHNlY3VyaXR5IG1vZGVsIHRvIGZyZWUgcHRyOiAlZFxuIiwKCQkgcGR1LT5zZWN1cml0eU1vZGVsKTsKICAgICAgfQogICAgICBwZHUtPnNlY3VyaXR5U3RhdGVSZWYgPSBOVUxMOwogICAgfQoKICAgIGZvciAocnAgPSBpc3AtPnJlcXVlc3RzOyBycDsgb3JwID0gcnAsIHJwID0gcnAtPm5leHRfcmVxdWVzdCkgewogICAgICBzbm1wX2NhbGxiYWNrICAgY2FsbGJhY2s7CiAgICAgIHZvaWQgICAgICAgICAgICptYWdpYzsKCiAgICAgIGlmIChwZHUtPnZlcnNpb24gPT0gU05NUF9WRVJTSU9OXzMpIHsKCS8qCgkgKiBtc2dJZCBtdXN0IG1hdGNoIGZvciB2MyBtZXNzYWdlcy4gIAoJICovCglpZiAocnAtPm1lc3NhZ2VfaWQgIT0gcGR1LT5tc2dpZCkgewoJICBjb250aW51ZTsKCX0KCgkvKgoJICogQ2hlY2sgdGhhdCBtZXNzYWdlIGZpZWxkcyBtYXRjaCBvcmlnaW5hbCwgaWYgbm90LCBubyBmdXJ0aGVyCgkgKiBwcm9jZXNzaW5nLiAgCgkgKi8KCWlmICghc25tcHYzX3ZlcmlmeV9tc2cocnAsIHBkdSkpIHsKCSAgYnJlYWs7Cgl9CiAgICAgIH0gZWxzZSB7CglpZiAocnAtPnJlcXVlc3RfaWQgIT0gcGR1LT5yZXFpZCkgewoJICBjb250aW51ZTsKCX0KICAgICAgfQoKICAgICAgaWYgKHJwLT5jYWxsYmFjaykgewoJY2FsbGJhY2sgPSBycC0+Y2FsbGJhY2s7CgltYWdpYyA9IHJwLT5jYl9kYXRhOwogICAgICB9IGVsc2UgewoJY2FsbGJhY2sgPSBzcC0+Y2FsbGJhY2s7CgltYWdpYyA9IHNwLT5jYWxsYmFja19tYWdpYzsKICAgICAgfQogICAgICBoYW5kbGVkID0gMTsKCiAgICAgIC8qCiAgICAgICAqIE1UUiBzbm1wX3Jlc19sb2NrKE1UX0xJQlJBUllfSUQsIE1UX0xJQl9TRVNTSU9OKTsgID8qIFhYIGxvY2sKICAgICAgICogc2hvdWxkIGJlIHBlciBzZXNzaW9uICEgCiAgICAgICAqLwoKICAgICAgaWYgKGNhbGxiYWNrID09IE5VTEwKCSAgfHwgY2FsbGJhY2soTkVUU05NUF9DQUxMQkFDS19PUF9SRUNFSVZFRF9NRVNTQUdFLCBzcCwKCQkgICAgICBwZHUtPnJlcWlkLCBwZHUsIG1hZ2ljKSA9PSAxKSB7CglpZiAocGR1LT5jb21tYW5kID09IFNOTVBfTVNHX1JFUE9SVCkgewoJICBpZiAoc3AtPnNfc25tcF9lcnJubyA9PSBTTk1QRVJSX05PVF9JTl9USU1FX1dJTkRPVyB8fAoJICAgICAgc25tcHYzX2dldF9yZXBvcnRfdHlwZShwZHUpID09CgkgICAgICBTTk1QRVJSX05PVF9JTl9USU1FX1dJTkRPVykgewoJICAgIC8qCgkgICAgICogdHJpZ2dlciBpbW1lZGlhdGUgcmV0cnkgb24gcmVjb3ZlcmFibGUgUmVwb3J0cyAKCSAgICAgKiAqIChub3RJblRpbWVXaW5kb3cpLCBpbmNyX3JldHJpZXMgPT0gVFJVRSB0byBwcmV2ZW50CgkgICAgICogKiBpbmlmaW5pdGUgcmVzZW5kICAgICAgICAgICAgICAgICAgICAgIAoJICAgICAqLwoJICAgIGlmIChycC0+cmV0cmllcyA8PSBzcC0+cmV0cmllcykgewoJICAgICAgc25tcF9yZXNlbmRfcmVxdWVzdChzbHAsIHJwLCBUUlVFKTsKCSAgICAgIGJyZWFrOwoJICAgIH0gZWxzZSB7CgkgICAgICAvKiBXZSdyZSBkb25lIHdpdGggcmV0cmllcywgc28gbm8gbG9uZ2VyIHdhaXRpbmcgZm9yIGEgcmVzcG9uc2UgKi8KCSAgICAgIGlmIChtYWdpYykgewoJCSgoc3RydWN0IHN5bmNoX3N0YXRlKiltYWdpYyktPndhaXRpbmcgPSAwOwoJICAgICAgfQoJICAgIH0KCSAgfSBlbHNlIHsKCSAgICBpZiAoU05NUFYzX0lHTk9SRV9VTkFVVEhfUkVQT1JUUykgewoJICAgICAgYnJlYWs7CgkgICAgfSBlbHNlIHsgLyogU2V0IHRoZSBzdGF0ZSB0byBubyBsb25nZXIgYmUgd2FpdGluZywgc2luY2Ugd2UncmUgZG9uZSB3aXRoIHJldHJpZXMgKi8KCSAgICAgIGlmIChtYWdpYykgewoJCSgoc3RydWN0IHN5bmNoX3N0YXRlKiltYWdpYyktPndhaXRpbmcgPSAwOwoJICAgICAgfQoJICAgIH0KCSAgfQoKCSAgLyoKCSAgICogSGFuZGxlIGVuZ2luZUlEIGRpc2NvdmVyeS4gIAoJICAgKi8KCSAgaWYgKCFzcC0+c2VjdXJpdHlFbmdpbmVJRExlbiAmJiBwZHUtPnNlY3VyaXR5RW5naW5lSURMZW4pIHsKCSAgICBzcC0+c2VjdXJpdHlFbmdpbmVJRCA9CgkgICAgICAodV9jaGFyICopIG1hbGxvYyhwZHUtPnNlY3VyaXR5RW5naW5lSURMZW4pOwoJICAgIGlmIChzcC0+c2VjdXJpdHlFbmdpbmVJRCA9PSBOVUxMKSB7CgkgICAgICAvKgoJICAgICAgICogVE9ETyBGSVg6IHJlY292ZXIgYWZ0ZXIgbWVzc2FnZSBjYWxsYmFjayAqPwogICAgICAgICAgICAgICAqLwoJICAgICAgcmV0dXJuIC0xOwoJICAgIH0KCSAgICBtZW1jcHkoc3AtPnNlY3VyaXR5RW5naW5lSUQsIHBkdS0+c2VjdXJpdHlFbmdpbmVJRCwKCQkgICBwZHUtPnNlY3VyaXR5RW5naW5lSURMZW4pOwoJICAgIHNwLT5zZWN1cml0eUVuZ2luZUlETGVuID0gcGR1LT5zZWN1cml0eUVuZ2luZUlETGVuOwoJICAgIGlmICghc3AtPmNvbnRleHRFbmdpbmVJRExlbikgewoJICAgICAgc3AtPmNvbnRleHRFbmdpbmVJRCA9CgkJKHVfY2hhciAqKSBtYWxsb2MocGR1LT4KCQkJCSAgc2VjdXJpdHlFbmdpbmVJRExlbik7CgkgICAgICBpZiAoc3AtPmNvbnRleHRFbmdpbmVJRCA9PSBOVUxMKSB7CgkJLyoKCQkgKiBUT0RPIEZJWDogcmVjb3ZlciBhZnRlciBtZXNzYWdlIGNhbGxiYWNrICo/CgkJICovCiAgICAgICAgICAgICAgICByZXR1cm4gLTE7CgkgICAgICB9CgkgICAgICBtZW1jcHkoc3AtPmNvbnRleHRFbmdpbmVJRCwKCQkgICAgIHBkdS0+c2VjdXJpdHlFbmdpbmVJRCwKCQkgICAgIHBkdS0+c2VjdXJpdHlFbmdpbmVJRExlbik7CgkgICAgICBzcC0+Y29udGV4dEVuZ2luZUlETGVuID0KCQlwZHUtPnNlY3VyaXR5RW5naW5lSURMZW47CgkgICAgfQoJICB9Cgl9CgoJLyoKCSAqIFN1Y2Nlc3NmdWwsIHNvIGRlbGV0ZSByZXF1ZXN0LiAgCgkgKi8KCWlmIChpc3AtPnJlcXVlc3RzID09IHJwKSB7CgkgIGlzcC0+cmVxdWVzdHMgPSBycC0+bmV4dF9yZXF1ZXN0OwoJICBpZiAoaXNwLT5yZXF1ZXN0c0VuZCA9PSBycCkgewoJICAgIGlzcC0+cmVxdWVzdHNFbmQgPSBOVUxMOwoJICB9Cgl9IGVsc2UgewoJICBvcnAtPm5leHRfcmVxdWVzdCA9IHJwLT5uZXh0X3JlcXVlc3Q7CgkgIGlmIChpc3AtPnJlcXVlc3RzRW5kID09IHJwKSB7CgkgICAgaXNwLT5yZXF1ZXN0c0VuZCA9IG9ycDsKCSAgfQoJfQoJc25tcF9mcmVlX3BkdShycC0+cGR1KTsKCWZyZWUoKGNoYXIgKikgcnApOwoJLyoKCSAqIFRoZXJlIHNob3VsZG4ndCBiZSBhbnkgbW9yZSByZXF1ZXN0cyB3aXRoIHRoZSBzYW1lIHJlcWlkLiAgCgkgKi8KCWJyZWFrOwogICAgICB9CiAgICAgIC8qCiAgICAgICAqIE1UUiBzbm1wX3Jlc191bmxvY2soTVRfTElCUkFSWV9JRCwgTVRfTElCX1NFU1NJT04pOyAgPyogWFggbG9jayBzaG91bGQgYmUgcGVyIHNlc3Npb24gISAKICAgICAgICovCiAgICB9CiAgfSBlbHNlIHsKICAgIGlmIChzcC0+Y2FsbGJhY2spIHsKICAgICAgLyoKICAgICAgICogTVRSIHNubXBfcmVzX2xvY2soTVRfTElCUkFSWV9JRCwgTVRfTElCX1NFU1NJT04pOyAKICAgICAgICovCiAgICAgIGhhbmRsZWQgPSAxOwogICAgICBzcC0+Y2FsbGJhY2soTkVUU05NUF9DQUxMQkFDS19PUF9SRUNFSVZFRF9NRVNTQUdFLAoJCSAgIHNwLCBwZHUtPnJlcWlkLCBwZHUsIHNwLT5jYWxsYmFja19tYWdpYyk7CiAgICAgIC8qCiAgICAgICAqIE1UUiBzbm1wX3Jlc191bmxvY2soTVRfTElCUkFSWV9JRCwgTVRfTElCX1NFU1NJT04pOyAKICAgICAgICovCiAgICB9CiAgfQoKICAvKgogICAqIENhbGwgVVNNIHRvIGZyZWUgYW55IHNlY3VyaXR5U3RhdGVSZWYgc3VwcGxpZWQgd2l0aCB0aGUgbWVzc2FnZS4gIAogICAqLwogIGlmIChwZHUgIT0gTlVMTCAmJiBwZHUtPnNlY3VyaXR5U3RhdGVSZWYgJiYKICAgICAgcGR1LT5jb21tYW5kID09IFNOTVBfTVNHX1RSQVAyKSB7CiAgICBzcHRyID0gZmluZF9zZWNfbW9kKHBkdS0+c2VjdXJpdHlNb2RlbCk7CiAgICBpZiAoc3B0cikgewogICAgICBpZiAoc3B0ci0+cGR1X2ZyZWVfc3RhdGVfcmVmKSB7CgkoKnNwdHItPnBkdV9mcmVlX3N0YXRlX3JlZikgKHBkdS0+c2VjdXJpdHlTdGF0ZVJlZik7CiAgICAgIH0gZWxzZSB7Cglzbm1wX2xvZyhMT0dfRVJSLAoJCSAiU2VjdXJpdHkgTW9kZWwgJWQgY2FuJ3QgZnJlZSBzdGF0ZSByZWZlcmVuY2VzXG4iLAoJCSBwZHUtPnNlY3VyaXR5TW9kZWwpOwogICAgICB9CiAgICB9IGVsc2UgewogICAgICBzbm1wX2xvZyhMT0dfRVJSLAoJICAgICAgICJDYW4ndCBmaW5kIHNlY3VyaXR5IG1vZGVsIHRvIGZyZWUgcHRyOiAlZFxuIiwKCSAgICAgICBwZHUtPnNlY3VyaXR5TW9kZWwpOwogICAgfQogICAgcGR1LT5zZWN1cml0eVN0YXRlUmVmID0gTlVMTDsKICB9CgogIGlmICghaGFuZGxlZCkgewogICAgc25tcF9pbmNyZW1lbnRfc3RhdGlzdGljKFNUQVRfU05NUFVOS05PV05QRFVIQU5ETEVSUyk7CiAgICBERUJVR01TR1RMKCgic2Vzc19wcm9jZXNzX3BhY2tldCIsICJ1bmhhbmRsZWQgUERVXG4iKSk7CiAgfQoKICBzbm1wX2ZyZWVfcGR1KHBkdSk7CiAgcmV0dXJuIDA7Cn0KCi8qCiAqIENoZWNrcyB0byBzZWUgaWYgYW55IG9mIHRoZSBmZCdzIHNldCBpbiB0aGUgZmRzZXQgYmVsb25nIHRvCiAqIHNubXAuICBFYWNoIHNvY2tldCB3aXRoIGl0J3MgZmQgc2V0IGhhcyBhIHBhY2tldCByZWFkIGZyb20gaXQKICogYW5kIHNubXBfcGFyc2UgaXMgY2FsbGVkIG9uIHRoZSBwYWNrZXQgcmVjZWl2ZWQuICBUaGUgcmVzdWx0aW5nIHBkdQogKiBpcyBwYXNzZWQgdG8gdGhlIGNhbGxiYWNrIHJvdXRpbmUgZm9yIHRoYXQgc2Vzc2lvbi4gIElmIHRoZSBjYWxsYmFjawogKiByb3V0aW5lIHJldHVybnMgc3VjY2Vzc2Z1bGx5LCB0aGUgcGR1IGFuZCBpdCdzIHJlcXVlc3QgYXJlIGRlbGV0ZWQuCiAqLwp2b2lkCnNubXBfcmVhZChmZF9zZXQgKiBmZHNldCkKewogICAgc3RydWN0IHNlc3Npb25fbGlzdCAqc2xwOwogICAgc25tcF9yZXNfbG9jayhNVF9MSUJSQVJZX0lELCBNVF9MSUJfU0VTU0lPTik7CiAgICBmb3IgKHNscCA9IFNlc3Npb25zOyBzbHA7IHNscCA9IHNscC0+bmV4dCkgewogICAgICAgIHNubXBfc2Vzc19yZWFkKCh2b2lkICopIHNscCwgZmRzZXQpOwogICAgfQogICAgc25tcF9yZXNfdW5sb2NrKE1UX0xJQlJBUllfSUQsIE1UX0xJQl9TRVNTSU9OKTsKfQoKLyoKICogU2FtZSBhcyBzbm1wX3JlYWQsIGJ1dCB3b3JrcyBqdXN0IG9uZSBzZXNzaW9uLiAKICogcmV0dXJucyAwIGlmIHN1Y2Nlc3MsIC0xIGlmIGZhaWwgCiAqIE1UUjogY2FuJ3QgbG9jayBoZXJlIGFuZCBhdCBzbm1wX3JlYWQgCiAqIEJld2FyZSByZWN1cnNpdmUgc2VuZCBtYXliZSBpbnNpZGUgc25tcF9yZWFkIGNhbGxiYWNrIGZ1bmN0aW9uLiAKICovCmludApfc2Vzc19yZWFkKHZvaWQgKnNlc3NwLCBmZF9zZXQgKiBmZHNldCkKewogICAgc3RydWN0IHNlc3Npb25fbGlzdCAqc2xwID0gKHN0cnVjdCBzZXNzaW9uX2xpc3QgKikgc2Vzc3A7CiAgICBuZXRzbm1wX3Nlc3Npb24gKnNwID0gc2xwID8gc2xwLT5zZXNzaW9uIDogTlVMTDsKICAgIHN0cnVjdCBzbm1wX2ludGVybmFsX3Nlc3Npb24gKmlzcCA9IHNscCA/IHNscC0+aW50ZXJuYWwgOiBOVUxMOwogICAgbmV0c25tcF90cmFuc3BvcnQgKnRyYW5zcG9ydCA9IHNscCA/IHNscC0+dHJhbnNwb3J0IDogTlVMTDsKICAgIHNpemVfdCAgICAgICAgICBwZHVsZW4gPSAwLCByeGJ1Zl9sZW4gPSA2NTUzNjsKICAgIHVfY2hhciAgICAgICAgICpyeGJ1ZiA9IE5VTEw7CiAgICBpbnQgICAgICAgICAgICAgbGVuZ3RoID0gMCwgb2xlbmd0aCA9IDAsIHJjID0gMDsKICAgIHZvaWQgICAgICAgICAgICpvcGFxdWUgPSBOVUxMOwoKICAgIGlmICghc3AgfHwgIWlzcCB8fCAhdHJhbnNwb3J0KSB7CiAgICAgICAgREVCVUdNU0dUTCgoInNlc3NfcmVhZCIsICJyZWFkIGZhaWw6IGNsb3NpbmcuLi5cbiIpKTsKICAgICAgICByZXR1cm4gMDsKICAgIH0KCiAgICAvKiB0byBhdm9pZCBzdWJhZ2VudCBjcmFzaCAqLyAKICAgIGlmICh0cmFuc3BvcnQtPnNvY2sgPCAwKSB7IAogICAgICAgIHNubXBfbG9nIChMT0dfSU5GTywgInRyYW5zcG9ydC0+c29jayBnb3QgbmVnYXRpdmUgZmQgdmFsdWUgJWRcbiIsIHRyYW5zcG9ydC0+c29jayk7CiAgICAgICAgcmV0dXJuIDA7IAogICAgfQoKICAgIGlmICghZmRzZXQgfHwgIShGRF9JU1NFVCh0cmFuc3BvcnQtPnNvY2ssIGZkc2V0KSkpIHsKICAgICAgICBERUJVR01TR1RMKCgic2Vzc19yZWFkIiwgIm5vdCByZWFkaW5nICVkIChmZHNldCAlcCBzZXQgJWQpXG4iLAogICAgICAgICAgICAgICAgICAgIHRyYW5zcG9ydC0+c29jaywgZmRzZXQsCiAgICAgICAgICAgICAgICAgICAgZmRzZXQgPyBGRF9JU1NFVCh0cmFuc3BvcnQtPnNvY2ssIGZkc2V0KSA6IC05KSk7CiAgICAgICAgcmV0dXJuIDA7CiAgICB9CgogICAgc3AtPnNfc25tcF9lcnJubyA9IDA7CiAgICBzcC0+c19lcnJubyA9IDA7CgogICAgaWYgKHRyYW5zcG9ydC0+ZmxhZ3MgJiBORVRTTk1QX1RSQU5TUE9SVF9GTEFHX0xJU1RFTikgewogICAgICAgIGludCAgICAgICAgICAgICBkYXRhX3NvY2sgPSB0cmFuc3BvcnQtPmZfYWNjZXB0KHRyYW5zcG9ydCk7CgogICAgICAgIGlmIChkYXRhX3NvY2sgPj0gMCkgewogICAgICAgICAgICAvKgogICAgICAgICAgICAgKiBXZSd2ZSBzdWNjZXNzZnVsbHkgYWNjZXB0ZWQgYSBuZXcgc3RyZWFtLWJhc2VkIGNvbm5lY3Rpb24uCiAgICAgICAgICAgICAqIEl0J3Mgbm90IHRvbyBjbGVhciB3aGF0IHNob3VsZCBoYXBwZW4gaGVyZSBpZiB3ZSBhcmUgdXNpbmcgdGhlCiAgICAgICAgICAgICAqIHNpbmdsZS1zZXNzaW9uIEFQSSBhdCB0aGlzIHBvaW50LiAgQmFzaWNhbGx5IGEgInNlc3Npb24KICAgICAgICAgICAgICogYWNjZXB0ZWQiIGNhbGxiYWNrIGlzIHByb2JhYmx5IG5lZWRlZCB0byBoYW5kIHRoZSBuZXcgc2Vzc2lvbgogICAgICAgICAgICAgKiBvdmVyIHRvIHRoZSBhcHBsaWNhdGlvbi4KICAgICAgICAgICAgICogCiAgICAgICAgICAgICAqIEhvd2V2ZXIsIGZvciBub3csIGFzIGluIHRoZSBvcmlnaW5hbCBzbm1wX2FwaSwgd2Ugd2lsbCBBU1NVTUUKICAgICAgICAgICAgICogdGhhdCB3ZSdyZSB1c2luZyB0aGUgdHJhZGl0aW9uYWwgQVBJLCBhbmQgc2ltcGx5IGFkZCB0aGUgbmV3CiAgICAgICAgICAgICAqIHNlc3Npb24gdG8gdGhlIGxpc3QuICBOb3RlIHdlIGRvbid0IGhhdmUgdG8gZ2V0IHRoZSBTZXNzaW9uCiAgICAgICAgICAgICAqIGxpc3QgbG9jayBoZXJlLCBiZWNhdXNlIHVuZGVyIHRoYXQgYXNzdW1wdGlvbiB3ZSBhbHJlYWR5IGhvbGQKICAgICAgICAgICAgICogaXQgKHRoaXMgaXMgYWxzbyB3aHkgd2UgZG9uJ3QganVzdCB1c2Ugc25tcF9hZGQpLgogICAgICAgICAgICAgKiAKICAgICAgICAgICAgICogVGhlIG1vcmFsIG9mIHRoZSBzdG9yeSBpczogZG9uJ3QgdXNlIGxpc3RlbmluZyBzdHJlYW0tYmFzZWQKICAgICAgICAgICAgICogdHJhbnNwb3J0cyBpbiBhIG11bHRpLXRocmVhZGVkIGVudmlyb25tZW50IGJlY2F1c2Ugc29tZXRoaW5nCiAgICAgICAgICAgICAqIHdpbGwgZ28gSE9SUklCTFkgd3JvbmcgKGFuZCBhbHNvIHRoYXQgU05NUC9UQ1AgaXMgbm90IHRyaXZpYWwpLgogICAgICAgICAgICAgKiAKICAgICAgICAgICAgICogQW5vdGhlciBvcGVuIGlzc3VlOiB3aGF0IHNob3VsZCBoYXBwZW4gdG8gc29ja2V0cyB0aGF0IGhhdmUKICAgICAgICAgICAgICogYmVlbiBhY2NlcHQoKWVkIGZyb20gYSBsaXN0ZW5pbmcgc29ja2V0IHdoZW4gdGhhdCBvcmlnaW5hbAogICAgICAgICAgICAgKiBzb2NrZXQgaXMgY2xvc2VkPyAgSWYgdGhleSBhcmUgbGVmdCBvcGVuLCB0aGVuIGF0dGVtcHRpbmcgdG8KICAgICAgICAgICAgICogcmUtb3BlbiB0aGUgbGlzdGVuaW5nIHNvY2tldCB3aWxsIGZhaWwsIHdoaWNoIGlzIHNlbWFudGljYWxseQogICAgICAgICAgICAgKiBjb25mdXNpbmcuICBQZXJoYXBzIHRoZXJlIHNob3VsZCBiZSBzb21lIGtpbmQgb2YgY2hhaW5pbmcgaW4KICAgICAgICAgICAgICogdGhlIHRyYW5zcG9ydCBzdHJ1Y3R1cmUgc28gdGhhdCB0aGV5IGNhbiBhbGwgYmUgY2xvc2VkLgogICAgICAgICAgICAgKiBEaXNjdXNzLiAgOy0pCiAgICAgICAgICAgICAqLwoKCSAgICBuZXRzbm1wX3RyYW5zcG9ydCAqbmV3X3RyYW5zcG9ydD1uZXRzbm1wX3RyYW5zcG9ydF9jb3B5KHRyYW5zcG9ydCk7CiAgICAgICAgICAgIGlmIChuZXdfdHJhbnNwb3J0ICE9IE5VTEwpIHsKICAgICAgICAgICAgICAgIHN0cnVjdCBzZXNzaW9uX2xpc3QgKm5zbHAgPSBOVUxMOwoKICAgICAgICAgICAgICAgIG5ld190cmFuc3BvcnQtPnNvY2sgPSBkYXRhX3NvY2s7CiAgICAgICAgICAgICAgICBuZXdfdHJhbnNwb3J0LT5mbGFncyAmPSB+TkVUU05NUF9UUkFOU1BPUlRfRkxBR19MSVNURU47CgogICAgICAgICAgICAgICAgbnNscCA9IChzdHJ1Y3Qgc2Vzc2lvbl9saXN0ICopc25tcF9zZXNzX2FkZF9leChzcCwKCQkJICBuZXdfdHJhbnNwb3J0LCBpc3AtPmhvb2tfcHJlLCBpc3AtPmhvb2tfcGFyc2UsCgkJCSAgaXNwLT5ob29rX3Bvc3QsIGlzcC0+aG9va19idWlsZCwKCQkJICBpc3AtPmhvb2tfcmVhbGxvY19idWlsZCwgaXNwLT5jaGVja19wYWNrZXQsCgkJCSAgaXNwLT5ob29rX2NyZWF0ZV9wZHUpOwoKICAgICAgICAgICAgICAgIGlmIChuc2xwICE9IE5VTEwpIHsKICAgICAgICAgICAgICAgICAgICBuc2xwLT5uZXh0ID0gU2Vzc2lvbnM7CiAgICAgICAgICAgICAgICAgICAgU2Vzc2lvbnMgPSBuc2xwOwogICAgICAgICAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAgICAgICAgICogVGVsbCB0aGUgbmV3IHNlc3Npb24gYWJvdXQgaXRzIGV4aXN0YW5jZSBpZiBwb3NzaWJsZS4KICAgICAgICAgICAgICAgICAgICAgKi8KICAgICAgICAgICAgICAgICAgICBERUJVR01TR1RMKCgic2Vzc19yZWFkIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAicGVyZm9ybSBjYWxsYmFjayB3aXRoIG9wPUNPTk5FQ1RcbiIpKTsKICAgICAgICAgICAgICAgICAgICAodm9pZCluc2xwLT5zZXNzaW9uLT5jYWxsYmFjayhORVRTTk1QX0NBTExCQUNLX09QX0NPTk5FQ1QsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbnNscC0+c2Vzc2lvbiwgMCwgTlVMTCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzcC0+Y2FsbGJhY2tfbWFnaWMpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgcmV0dXJuIDA7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBzcC0+c19zbm1wX2Vycm5vID0gU05NUEVSUl9NQUxMT0M7CiAgICAgICAgICAgICAgICBzcC0+c19lcnJubyA9IGVycm5vOwogICAgICAgICAgICAgICAgc25tcF9zZXRfZGV0YWlsKHN0cmVycm9yKGVycm5vKSk7CiAgICAgICAgICAgICAgICByZXR1cm4gLTE7CiAgICAgICAgICAgIH0KICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBzcC0+c19zbm1wX2Vycm5vID0gU05NUEVSUl9CQURfUkVDVkZST007CiAgICAgICAgICAgIHNwLT5zX2Vycm5vID0gZXJybm87CiAgICAgICAgICAgIHNubXBfc2V0X2RldGFpbChzdHJlcnJvcihlcnJubykpOwogICAgICAgICAgICByZXR1cm4gLTE7CiAgICAgICAgfQogICAgfQoKICAgIC8qCiAgICAgKiBXb3JrIG91dCB3aGVyZSB0byByZWNlaXZlIHRoZSBkYXRhIHRvLiAgCiAgICAgKi8KCiAgICBpZiAodHJhbnNwb3J0LT5mbGFncyAmIE5FVFNOTVBfVFJBTlNQT1JUX0ZMQUdfU1RSRUFNKSB7CiAgICAgICAgaWYgKGlzcC0+cGFja2V0ID09IE5VTEwpIHsKICAgICAgICAgICAgLyoKICAgICAgICAgICAgICogV2UgaGF2ZSBubyBzYXZlZCBwYWNrZXQuICBBbGxvY2F0ZSBvbmUuICAKICAgICAgICAgICAgICovCiAgICAgICAgICAgIGlmICgoaXNwLT5wYWNrZXQgPSAodV9jaGFyICopIG1hbGxvYyhyeGJ1Zl9sZW4pKSA9PSBOVUxMKSB7CiAgICAgICAgICAgICAgICBERUJVR01TR1RMKCgic2Vzc19yZWFkIiwgImNhbid0IG1hbGxvYyAlZCBieXRlcyBmb3IgcnhidWZcbiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICByeGJ1Zl9sZW4pKTsKICAgICAgICAgICAgICAgIHJldHVybiAwOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgcnhidWYgPSBpc3AtPnBhY2tldDsKICAgICAgICAgICAgICAgIGlzcC0+cGFja2V0X3NpemUgPSByeGJ1Zl9sZW47CiAgICAgICAgICAgICAgICBpc3AtPnBhY2tldF9sZW4gPSAwOwogICAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgLyoKICAgICAgICAgICAgICogV2UgaGF2ZSBzYXZlZCBhIHBhcnRpYWwgcGFja2V0IGZyb20gbGFzdCB0aW1lLiAgRXh0ZW5kIHRoYXQsIGlmCiAgICAgICAgICAgICAqIG5lY2Vzc2FyeSwgYW5kIHJlY2VpdmUgbmV3IGRhdGEgYWZ0ZXIgdGhlIG9sZCBkYXRhLiAgCiAgICAgICAgICAgICAqLwogICAgICAgICAgICB1X2NoYXIgICAgICAgICAqbmV3YnVmOwoKICAgICAgICAgICAgaWYgKGlzcC0+cGFja2V0X3NpemUgPCBpc3AtPnBhY2tldF9sZW4gKyByeGJ1Zl9sZW4pIHsKICAgICAgICAgICAgICAgIG5ld2J1ZiA9CiAgICAgICAgICAgICAgICAgICAgKHVfY2hhciAqKSByZWFsbG9jKGlzcC0+cGFja2V0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpc3AtPnBhY2tldF9sZW4gKyByeGJ1Zl9sZW4pOwogICAgICAgICAgICAgICAgaWYgKG5ld2J1ZiA9PSBOVUxMKSB7CiAgICAgICAgICAgICAgICAgICAgREVCVUdNU0dUTCgoInNlc3NfcmVhZCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgImNhbid0IG1hbGxvYyAlZCBtb3JlIGZvciByeGJ1ZiAoJWQgdG90KVxuIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByeGJ1Zl9sZW4sIGlzcC0+cGFja2V0X2xlbiArIHJ4YnVmX2xlbikpOwogICAgICAgICAgICAgICAgICAgIHJldHVybiAwOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICBpc3AtPnBhY2tldCA9IG5ld2J1ZjsKICAgICAgICAgICAgICAgICAgICBpc3AtPnBhY2tldF9zaXplID0gaXNwLT5wYWNrZXRfbGVuICsgcnhidWZfbGVuOwogICAgICAgICAgICAgICAgICAgIHJ4YnVmID0gaXNwLT5wYWNrZXQgKyBpc3AtPnBhY2tldF9sZW47CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICByeGJ1ZiA9IGlzcC0+cGFja2V0ICsgaXNwLT5wYWNrZXRfbGVuOwogICAgICAgICAgICAgICAgcnhidWZfbGVuID0gaXNwLT5wYWNrZXRfc2l6ZSAtIGlzcC0+cGFja2V0X2xlbjsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0gZWxzZSB7CiAgICAgICAgaWYgKChyeGJ1ZiA9ICh1X2NoYXIgKikgbWFsbG9jKHJ4YnVmX2xlbikpID09IE5VTEwpIHsKICAgICAgICAgICAgREVCVUdNU0dUTCgoInNlc3NfcmVhZCIsICJjYW4ndCBtYWxsb2MgJWQgYnl0ZXMgZm9yIHJ4YnVmXG4iLAogICAgICAgICAgICAgICAgICAgICAgICByeGJ1Zl9sZW4pKTsKICAgICAgICAgICAgcmV0dXJuIDA7CiAgICAgICAgfQogICAgfQoKICAgIGxlbmd0aCA9IHRyYW5zcG9ydC0+Zl9yZWN2KHRyYW5zcG9ydCwgcnhidWYsIHJ4YnVmX2xlbiwgJm9wYXF1ZSwgJm9sZW5ndGgpOwoKICAgIGlmIChsZW5ndGggPT0gLTEgJiYgISh0cmFuc3BvcnQtPmZsYWdzICYgTkVUU05NUF9UUkFOU1BPUlRfRkxBR19TVFJFQU0pKSB7CiAgICAgICAgc3AtPnNfc25tcF9lcnJubyA9IFNOTVBFUlJfQkFEX1JFQ1ZGUk9NOwogICAgICAgIHNwLT5zX2Vycm5vID0gZXJybm87CiAgICAgICAgc25tcF9zZXRfZGV0YWlsKHN0cmVycm9yKGVycm5vKSk7CiAgICAgICAgU05NUF9GUkVFKHJ4YnVmKTsKICAgICAgICBpZiAob3BhcXVlICE9IE5VTEwpIHsKICAgICAgICAgICAgU05NUF9GUkVFKG9wYXF1ZSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiAtMTsKICAgIH0KCiAgICAvKgogICAgICogUmVtb3RlIGVuZCBjbG9zZWQgY29ubmVjdGlvbi4gIAogICAgICovCgogICAgaWYgKGxlbmd0aCA8PSAwICYmIHRyYW5zcG9ydC0+ZmxhZ3MgJiBORVRTTk1QX1RSQU5TUE9SVF9GTEFHX1NUUkVBTSkgewogICAgICAgIC8qCiAgICAgICAgICogQWxlcnQgdGhlIGFwcGxpY2F0aW9uIGlmIHBvc3NpYmxlLiAgCiAgICAgICAgICovCiAgICAgICAgaWYgKHNwLT5jYWxsYmFjayAhPSBOVUxMKSB7CiAgICAgICAgICAgIERFQlVHTVNHVEwoKCJzZXNzX3JlYWQiLCAicGVyZm9ybSBjYWxsYmFjayB3aXRoIG9wPURJU0NPTk5FQ1RcbiIpKTsKICAgICAgICAgICAgKHZvaWQpIHNwLT5jYWxsYmFjayhORVRTTk1QX0NBTExCQUNLX09QX0RJU0NPTk5FQ1QsIHNwLCAwLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5VTEwsIHNwLT5jYWxsYmFja19tYWdpYyk7CiAgICAgICAgfQogICAgICAgIC8qCiAgICAgICAgICogQ2xvc2Ugc29ja2V0IGFuZCBtYXJrIHNlc3Npb24gZm9yIGRlbGV0aW9uLiAgCiAgICAgICAgICovCiAgICAgICAgREVCVUdNU0dUTCgoInNlc3NfcmVhZCIsICJmZCAlZCBjbG9zZWRcbiIsIHRyYW5zcG9ydC0+c29jaykpOwogICAgICAgIHRyYW5zcG9ydC0+Zl9jbG9zZSh0cmFuc3BvcnQpOwogICAgICAgIFNOTVBfRlJFRShpc3AtPnBhY2tldCk7CiAgICAgICAgaWYgKG9wYXF1ZSAhPSBOVUxMKSB7CiAgICAgICAgICAgIFNOTVBfRlJFRShvcGFxdWUpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gLTE7CiAgICB9CgogICAgaWYgKHRyYW5zcG9ydC0+ZmxhZ3MgJiBORVRTTk1QX1RSQU5TUE9SVF9GTEFHX1NUUkVBTSkgewogICAgICAgIHVfY2hhciAqcHB0ciA9IGlzcC0+cGFja2V0OwoJdm9pZCAqb2NvcHkgPSBOVUxMOwoKICAgICAgICBpc3AtPnBhY2tldF9sZW4gKz0gbGVuZ3RoOwoKICAgICAgICB3aGlsZSAoaXNwLT5wYWNrZXRfbGVuID4gMCkgewoKICAgICAgICAgICAgLyoKICAgICAgICAgICAgICogR2V0IHRoZSB0b3RhbCBkYXRhIGxlbmd0aCB3ZSdyZSBleHBlY3RpbmcgKGFuZCBuZWVkIHRvIHdhaXQKICAgICAgICAgICAgICogZm9yKS4KICAgICAgICAgICAgICovCiAgICAgICAgICAgIGlmIChpc3AtPmNoZWNrX3BhY2tldCkgewogICAgICAgICAgICAgICAgcGR1bGVuID0gaXNwLT5jaGVja19wYWNrZXQocHB0ciwgaXNwLT5wYWNrZXRfbGVuKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIHBkdWxlbiA9IGFzbl9jaGVja19wYWNrZXQocHB0ciwgaXNwLT5wYWNrZXRfbGVuKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgREVCVUdNU0dUTCgoInNlc3NfcmVhZCIsICIgIGxvb3AgcGFja2V0X2xlbiAlZCwgUERVIGxlbmd0aCAlZFxuIiwKICAgICAgICAgICAgICAgICAgICAgICAgaXNwLT5wYWNrZXRfbGVuLCBwZHVsZW4pKTsKICAgICAgICAgICAgIAogICAgICAgICAgICBpZiAoKHBkdWxlbiA+IE1BWF9QQUNLRVRfTEVOR1RIKSB8fCAocGR1bGVuIDwgMCkpIHsKICAgICAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAgICAgKiBJbGxlZ2FsIGxlbmd0aCwgZHJvcCB0aGUgY29ubmVjdGlvbi4gIAogICAgICAgICAgICAgICAgICovCiAgICAgICAgICAgICAgICBzbm1wX2xvZyhMT0dfRVJSLCAKCQkJICJSZWNlaXZlZCBicm9rZW4gcGFja2V0LiBDbG9zaW5nIHNlc3Npb24uXG4iKTsKCQlpZiAoc3AtPmNhbGxiYWNrICE9IE5VTEwpIHsKCQkgIERFQlVHTVNHVEwoKCJzZXNzX3JlYWQiLAoJCQkgICAgICAicGVyZm9ybSBjYWxsYmFjayB3aXRoIG9wPURJU0NPTk5FQ1RcbiIpKTsKCQkgICh2b2lkKXNwLT5jYWxsYmFjayhORVRTTk1QX0NBTExCQUNLX09QX0RJU0NPTk5FQ1QsCgkJCQkgICAgIHNwLCAwLCBOVUxMLCBzcC0+Y2FsbGJhY2tfbWFnaWMpOwoJCX0KCQlERUJVR01TR1RMKCgic2Vzc19yZWFkIiwgImZkICVkIGNsb3NlZFxuIiwgdHJhbnNwb3J0LT5zb2NrKSk7CiAgICAgICAgICAgICAgICB0cmFuc3BvcnQtPmZfY2xvc2UodHJhbnNwb3J0KTsKICAgICAgICAgICAgICAgIGlmIChvcGFxdWUgIT0gTlVMTCkgewogICAgICAgICAgICAgICAgICAgIFNOTVBfRlJFRShvcGFxdWUpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgLyoqIFhYWC1ya3M6IHdoeSBubyBTTk1QX0ZSRUUoaXNwLT5wYWNrZXQpOyA/PyAqLwogICAgICAgICAgICAgICAgcmV0dXJuIC0xOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAocGR1bGVuID4gaXNwLT5wYWNrZXRfbGVuIHx8IHBkdWxlbiA9PSAwKSB7CiAgICAgICAgICAgICAgICAvKgogICAgICAgICAgICAgICAgICogV2UgZG9uJ3QgaGF2ZSBhIGNvbXBsZXRlIHBhY2tldCB5ZXQuICBJZiB3ZSd2ZSBhbHJlYWR5CiAgICAgICAgICAgICAgICAgKiBwcm9jZXNzZWQgYSBwYWNrZXQsIGJyZWFrIG91dCBzbyB3ZSdsbCBzaGlmdCB0aGlzIHBhY2tldAogICAgICAgICAgICAgICAgICogdG8gdGhlIHN0YXJ0IG9mIHRoZSBidWZmZXIuIElmIHdlJ3JlIGFscmVhZHkgYXQgdGhlCiAgICAgICAgICAgICAgICAgKiBzdGFydCwgc2ltcGx5IHJldHVybiBhbmQgd2FpdCBmb3IgbW9yZSBkYXRhIHRvIGFycml2ZS4KICAgICAgICAgICAgICAgICAqLwogICAgICAgICAgICAgICAgREVCVUdNU0dUTCgoInNlc3NfcmVhZCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAicGt0IG5vdCBjb21wbGV0ZSAobmVlZCAlZCBnb3QgJWQgc28gZmFyKVxuIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBkdWxlbiwgaXNwLT5wYWNrZXRfbGVuKSk7CgogICAgICAgICAgICAgICAgaWYgKHBwdHIgIT0gaXNwLT5wYWNrZXQpCiAgICAgICAgICAgICAgICAgICAgYnJlYWs7IC8qIG9wYXF1ZSBmcmVlZCBmb3IgdXMgb3V0c2lkZSBvZiBsb29wLiAqLwoKICAgICAgICAgICAgICAgIGlmIChvcGFxdWUgIT0gTlVMTCkgewogICAgICAgICAgICAgICAgICAgIFNOTVBfRlJFRShvcGFxdWUpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgcmV0dXJuIDA7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8qICBXZSBoYXZlICphdCBsZWFzdCogb25lIGNvbXBsZXRlIHBhY2tldCBpbiB0aGUgYnVmZmVyIG5vdy4gIElmCgkJd2UgaGF2ZSBwb3NzaWJseSBtb3JlIHRoYW4gb25lIHBhY2tldCwgd2UgbXVzdCBjb3B5IHRoZSBvcGFxdWUKCQlwb2ludGVyIGJlY2F1c2Ugd2UgbWF5IG5lZWQgdG8gcmV1c2UgaXQgZm9yIGEgbGF0ZXIgcGFja2V0LiAgKi8KCgkgICAgaWYgKHBkdWxlbiA8IGlzcC0+cGFja2V0X2xlbikgewoJCWlmIChvbGVuZ3RoID4gMCAmJiBvcGFxdWUgIT0gTlVMTCkgewoJCSAgICBvY29weSA9IG1hbGxvYyhvbGVuZ3RoKTsKCQkgICAgaWYgKG9jb3B5ICE9IE5VTEwpIHsKCQkJbWVtY3B5KG9jb3B5LCBvcGFxdWUsIG9sZW5ndGgpOwoJCSAgICB9CgkJfQoJICAgIH0gZWxzZSBpZiAocGR1bGVuID09IGlzcC0+cGFja2V0X2xlbikgewoJCS8qICBDb21tb24gY2FzZSAtLSBleGFjdGx5IG9uZSBwYWNrZXQuICBObyBuZWVkIHRvIGNvcHkgdGhlCgkJICAgIG9wYXF1ZSBwb2ludGVyLiAgKi8KCQlvY29weSA9IG9wYXF1ZTsKCQlvcGFxdWUgPSBOVUxMOwoJICAgIH0KCiAgICAgICAgICAgIGlmICgocmMgPSBfc2Vzc19wcm9jZXNzX3BhY2tldChzZXNzcCwgc3AsIGlzcCwgdHJhbnNwb3J0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb2NvcHksIG9jb3B5P29sZW5ndGg6MCwgcHB0ciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBkdWxlbikpKSB7CiAgICAgICAgICAgICAgICAvKgogICAgICAgICAgICAgICAgICogU29tZXRoaW5nIHdlbnQgd3Jvbmcgd2hpbGUgcHJvY2Vzc2luZyB0aGlzIHBhY2tldCAtLSBzZXQgdGhlCiAgICAgICAgICAgICAgICAgKiBlcnJuby4gIAogICAgICAgICAgICAgICAgICovCiAgICAgICAgICAgICAgICBpZiAoc3AtPnNfc25tcF9lcnJubyAhPSAwKSB7CiAgICAgICAgICAgICAgICAgICAgU0VUX1NOTVBfRVJST1Ioc3AtPnNfc25tcF9lcnJubyk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCgkgICAgLyogIG9jb3B5IGhhcyBiZWVuIGZyZWUoKWQgYnkgX3Nlc3NfcHJvY2Vzc19wYWNrZXQgYnkgdGhpcyBwb2ludCwKCQlzbyBzZXQgaXQgdG8gTlVMTC4gICovCgoJICAgIG9jb3B5ID0gTlVMTDsKCgkgICAgLyogIFN0ZXAgcGFzdCB0aGUgcGFja2V0IHdlJ3ZlIGp1c3QgZGVhbHQgd2l0aC4gICovCgogICAgICAgICAgICBwcHRyICs9IHBkdWxlbjsKICAgICAgICAgICAgaXNwLT5wYWNrZXRfbGVuIC09IHBkdWxlbjsKICAgICAgICB9CgoJLyogIElmIHdlIGhhZCBtb3JlIHRoYW4gb25lIHBhY2tldCwgdGhlbiB3ZSB3ZXJlIHdvcmtpbmcgd2l0aCBjb3BpZXMKCSAgICBvZiB0aGUgb3BhcXVlIHBvaW50ZXIsIHNvIHdlIHN0aWxsIG5lZWQgdG8gZnJlZSgpIHRoZSBvcGFxdWUKCSAgICBwb2ludGVyIGl0c2VsZi4gICovCgoJaWYgKG9wYXF1ZSAhPSBOVUxMKSB7CgkgICAgU05NUF9GUkVFKG9wYXF1ZSk7Cgl9CgogICAgICAgIGlmIChpc3AtPnBhY2tldF9sZW4gPj0gTUFYSU1VTV9QQUNLRVRfU0laRSkgewogICAgICAgICAgICAvKgogICAgICAgICAgICAgKiBPYnZpb3VzbHkgdGhpcyBzaG91bGQgbmV2ZXIgaGFwcGVuISAgCiAgICAgICAgICAgICAqLwogICAgICAgICAgICBzbm1wX2xvZyhMT0dfRVJSLAogICAgICAgICAgICAgICAgICAgICAidG9vIGxhcmdlIHBhY2tldF9sZW4gPSAlbHUsIGRyb3BwaW5nIGNvbm5lY3Rpb24gJWRcbiIsCiAgICAgICAgICAgICAgICAgICAgICh1bnNpZ25lZCBsb25nKShpc3AtPnBhY2tldF9sZW4pLCB0cmFuc3BvcnQtPnNvY2spOwogICAgICAgICAgICB0cmFuc3BvcnQtPmZfY2xvc2UodHJhbnNwb3J0KTsKICAgICAgICAgICAgLyoqIFhYWC1ya3M6IHdoeSBubyBTTk1QX0ZSRUUoaXNwLT5wYWNrZXQpOyA/PyAqLwogICAgICAgICAgICByZXR1cm4gLTE7CiAgICAgICAgfSBlbHNlIGlmIChpc3AtPnBhY2tldF9sZW4gPT0gMCkgewogICAgICAgICAgICAvKgogICAgICAgICAgICAgKiBUaGlzIGlzIGdvb2Q6IGl0IG1lYW5zIHRoZSBwYWNrZXQgYnVmZmVyIGNvbnRhaW5lZCBhbiBpbnRlZ3JhbAogICAgICAgICAgICAgKiBudW1iZXIgb2YgUERVcywgc28gd2UgZG9uJ3QgaGF2ZSB0byBzYXZlIGFueSBkYXRhIGZvciBuZXh0CiAgICAgICAgICAgICAqIHRpbWUuICBXZSBjYW4gZnJlZSgpIHRoZSBidWZmZXIgbm93IHRvIGtlZXAgdGhlIG1lbW9yeQogICAgICAgICAgICAgKiBmb290cHJpbnQgZG93bi4KICAgICAgICAgICAgICovCiAgICAgICAgICAgIFNOTVBfRlJFRShpc3AtPnBhY2tldCk7CiAgICAgICAgICAgIGlzcC0+cGFja2V0ID0gTlVMTDsKICAgICAgICAgICAgaXNwLT5wYWNrZXRfc2l6ZSA9IDA7CiAgICAgICAgICAgIGlzcC0+cGFja2V0X2xlbiA9IDA7CiAgICAgICAgICAgIHJldHVybiByYzsKICAgICAgICB9CgogICAgICAgIC8qCiAgICAgICAgICogSWYgd2UgZ2V0IGhlcmUsIHRoZW4gdGhlcmUgaXMgYSBwYXJ0aWFsIHBhY2tldCBvZiBsZW5ndGgKICAgICAgICAgKiBpc3AtPnBhY2tldF9sZW4gYnl0ZXMgc3RhcnRpbmcgYXQgcHB0ciBsZWZ0IG92ZXIuICBNb3ZlIHRoYXQgdG8gdGhlCiAgICAgICAgICogc3RhcnQgb2YgdGhlIGJ1ZmZlciwgYW5kIHRoZW4gcmVhbGxvYygpIHRoZSBidWZmZXIgZG93biB0byBzaXplIHRvCiAgICAgICAgICogcmVkdWNlIHRoZSBtZW1vcnkgZm9vdHByaW50LiAgCiAgICAgICAgICovCgogICAgICAgIG1lbW1vdmUoaXNwLT5wYWNrZXQsIHBwdHIsIGlzcC0+cGFja2V0X2xlbik7CiAgICAgICAgREVCVUdNU0dUTCgoInNlc3NfcmVhZCIsICJlbmQ6IG1lbW1vdmUoJXAsICVwLCAlZCk7IHJlYWxsb2MoJXAsICVkKVxuIiwKICAgICAgICAgICAgICAgICAgICBpc3AtPnBhY2tldCwgcHB0ciwgaXNwLT5wYWNrZXRfbGVuLCBpc3AtPnBhY2tldCwKICAgICAgICAgICAgICAgICAgICBpc3AtPnBhY2tldF9sZW4pKTsKCiAgICAgICAgaWYgKChyeGJ1ZiA9ICh1X2NoYXIgKilyZWFsbG9jKGlzcC0+cGFja2V0LCBpc3AtPnBhY2tldF9sZW4pKSA9PSBOVUxMKSB7CiAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAqIEkgZG9uJ3Qgc2VlIHdoeSB0aGlzIHNob3VsZCBldmVyIGZhaWwsIGJ1dCBpdCdzIG5vdCBhIGJpZyBkZWFsLgogICAgICAgICAgICAgKi8KICAgICAgICAgICAgREVCVUdNU0dUTCgoInNlc3NfcmVhZCIsICJyZWFsbG9jKCkgZmFpbGVkXG4iKSk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgREVCVUdNU0dUTCgoInNlc3NfcmVhZCIsICJyZWFsbG9jKCkgb2theSwgb2xkIGJ1ZmZlciAlcCwgbmV3ICVwXG4iLAogICAgICAgICAgICAgICAgICAgICAgICBpc3AtPnBhY2tldCwgcnhidWYpKTsKICAgICAgICAgICAgaXNwLT5wYWNrZXQgPSByeGJ1ZjsKICAgICAgICAgICAgaXNwLT5wYWNrZXRfc2l6ZSA9IGlzcC0+cGFja2V0X2xlbjsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHJjOwogICAgfSBlbHNlIHsKICAgICAgICByYyA9IF9zZXNzX3Byb2Nlc3NfcGFja2V0KHNlc3NwLCBzcCwgaXNwLCB0cmFuc3BvcnQsIG9wYXF1ZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9sZW5ndGgsIHJ4YnVmLCBsZW5ndGgpOwogICAgICAgIFNOTVBfRlJFRShyeGJ1Zik7CiAgICAgICAgcmV0dXJuIHJjOwogICAgfQp9CgoKCi8qCiAqIHJldHVybnMgMCBpZiBzdWNjZXNzLCAtMSBpZiBmYWlsIAogKi8KaW50CnNubXBfc2Vzc19yZWFkKHZvaWQgKnNlc3NwLCBmZF9zZXQgKiBmZHNldCkKewogICAgc3RydWN0IHNlc3Npb25fbGlzdCAqcHNsOwogICAgbmV0c25tcF9zZXNzaW9uICpwc3M7CiAgICBpbnQgICAgICAgICAgICAgcmM7CgogICAgcmMgPSBfc2Vzc19yZWFkKHNlc3NwLCBmZHNldCk7CiAgICBwc2wgPSAoc3RydWN0IHNlc3Npb25fbGlzdCAqKSBzZXNzcDsKICAgIHBzcyA9IHBzbC0+c2Vzc2lvbjsKICAgIGlmIChyYyAmJiBwc3MtPnNfc25tcF9lcnJubykgewogICAgICAgIFNFVF9TTk1QX0VSUk9SKHBzcy0+c19zbm1wX2Vycm5vKTsKICAgIH0KICAgIHJldHVybiByYzsKfQoKCi8qCiAqIFJldHVybnMgaW5mbyBhYm91dCB3aGF0IHNubXAgcmVxdWlyZXMgZnJvbSBhIHNlbGVjdCBzdGF0ZW1lbnQuCiAqIG51bWZkcyBpcyB0aGUgbnVtYmVyIG9mIGZkcyBpbiB0aGUgbGlzdCB0aGF0IGFyZSBzaWduaWZpY2FudC4KICogQWxsIGZpbGUgZGVzY3JpcHRvcnMgb3BlbmVkIGZvciBTTk1QIGFyZSBPUidkIGludG8gdGhlIGZkc2V0LgogKiBJZiBhY3Rpdml0eSBvY2N1cnMgb24gYW55IG9mIHRoZXNlIGZpbGUgZGVzY3JpcHRvcnMsIHNubXBfcmVhZAogKiBzaG91bGQgYmUgY2FsbGVkIHdpdGggdGhhdCBmaWxlIGRlc2NyaXB0b3Igc2V0CiAqCiAqIFRoZSB0aW1lb3V0IGlzIHRoZSBsYXRlc3QgdGltZSB0aGF0IFNOTVAgY2FuIHdhaXQgZm9yIGEgdGltZW91dC4gIFRoZQogKiBzZWxlY3Qgc2hvdWxkIGJlIGRvbmUgd2l0aCB0aGUgbWluaW11bSB0aW1lIGJldHdlZW4gdGltZW91dCBhbmQgYW55IG90aGVyCiAqIHRpbWVvdXRzIG5lY2Vzc2FyeS4gIFRoaXMgc2hvdWxkIGJlIGNoZWNrZWQgdXBvbiBlYWNoIGludm9jYXRpb24gb2Ygc2VsZWN0LgogKiBJZiBhIHRpbWVvdXQgaXMgcmVjZWl2ZWQsIHNubXBfdGltZW91dCBzaG91bGQgYmUgY2FsbGVkIHRvIGNoZWNrIGlmIHRoZQogKiB0aW1lb3V0IHdhcyBmb3IgU05NUC4gIChzbm1wX3RpbWVvdXQgaXMgaWRlbXBvdGVudCkKICoKICogVGhlIHZhbHVlIG9mIGJsb2NrIGluZGljYXRlcyBob3cgdGhlIHRpbWVvdXQgdmFsdWUgaXMgaW50ZXJwcmV0ZWQuCiAqIElmIGJsb2NrIGlzIHRydWUgb24gaW5wdXQsIHRoZSB0aW1lb3V0IHZhbHVlIHdpbGwgYmUgdHJlYXRlZCBhcyB1bmRlZmluZWQsCiAqIGJ1dCBpdCBtdXN0IGJlIGF2YWlsYWJsZSBmb3Igc2V0dGluZyBpbiBzbm1wX3NlbGVjdF9pbmZvLiAgT24gcmV0dXJuLAogKiBibG9jayBpcyBzZXQgdG8gdHJ1ZSBpZiB0aGUgdmFsdWUgcmV0dXJuZWQgZm9yIHRpbWVvdXQgaXMgdW5kZWZpbmVkOwogKiB3aGVuIGJsb2NrIGlzIHNldCB0byBmYWxzZSwgdGltZW91dCBtYXkgYmUgdXNlZCBhcyBhIHBhcm1ldGVyIHRvICdzZWxlY3QnLgogKgogKiBzbm1wX3NlbGVjdF9pbmZvIHJldHVybnMgdGhlIG51bWJlciBvZiBvcGVuIHNvY2tldHMuICAoaS5lLiBUaGUgbnVtYmVyIG9mCiAqIHNlc3Npb25zIG9wZW4pCiAqLwoKaW50CnNubXBfc2VsZWN0X2luZm8oaW50ICpudW1mZHMsCiAgICAgICAgICAgICAgICAgZmRfc2V0ICogZmRzZXQsIHN0cnVjdCB0aW1ldmFsICp0aW1lb3V0LCBpbnQgKmJsb2NrKQogICAgLyoKICAgICAqIGlucHV0OiAgc2V0IHRvIDEgaWYgaW5wdXQgdGltZW91dCB2YWx1ZSBpcyB1bmRlZmluZWQgIAogICAgICogc2V0IHRvIDAgaWYgaW5wdXQgdGltZW91dCB2YWx1ZSBpcyBkZWZpbmVkICAgIAogICAgICogb3V0cHV0OiBzZXQgdG8gMSBpZiBvdXRwdXQgdGltZW91dCB2YWx1ZSBpcyB1bmRlZmluZWQgCiAgICAgKiBzZXQgdG8gMCBpZiBvdXRwdXQgcmltZW91dCB2bGF1ZSBpZCBkZWZpbmVkICAgCiAgICAgKi8KewogICAgcmV0dXJuIHNubXBfc2Vzc19zZWxlY3RfaW5mbygodm9pZCAqKSAwLCBudW1mZHMsIGZkc2V0LCB0aW1lb3V0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBibG9jayk7Cn0KCi8qCiAqIFNhbWUgYXMgc25tcF9zZWxlY3RfaW5mbywgYnV0IHdvcmtzIGp1c3Qgb25lIHNlc3Npb24uIAogKi8KaW50CnNubXBfc2Vzc19zZWxlY3RfaW5mbyh2b2lkICpzZXNzcCwKICAgICAgICAgICAgICAgICAgICAgIGludCAqbnVtZmRzLAogICAgICAgICAgICAgICAgICAgICAgZmRfc2V0ICogZmRzZXQsIHN0cnVjdCB0aW1ldmFsICp0aW1lb3V0LCBpbnQgKmJsb2NrKQp7CiAgICBzdHJ1Y3Qgc2Vzc2lvbl9saXN0ICpzbHB0ZXN0ID0gKHN0cnVjdCBzZXNzaW9uX2xpc3QgKikgc2Vzc3A7CiAgICBzdHJ1Y3Qgc2Vzc2lvbl9saXN0ICpzbHAsICpuZXh0ID0gTlVMTDsKICAgIG5ldHNubXBfcmVxdWVzdF9saXN0ICpycDsKICAgIHN0cnVjdCB0aW1ldmFsICBub3csIGVhcmxpZXN0LCBkZWx0YTsKICAgIGludCAgICAgICAgICAgICBhY3RpdmUgPSAwLCByZXF1ZXN0cyA9IDA7CiAgICBpbnQgICAgICAgICAgICAgbmV4dF9hbGFybSA9IDA7CgogICAgdGltZXJjbGVhcigmZWFybGllc3QpOwoKICAgIC8qCiAgICAgKiBGb3IgZWFjaCByZXF1ZXN0IG91dHN0YW5kaW5nLCBhZGQgaXRzIHNvY2tldCB0byB0aGUgZmRzZXQsCiAgICAgKiBhbmQgaWYgaXQgaXMgdGhlIGVhcmxpZXN0IHRpbWVvdXQgdG8gZXhwaXJlLCBtYXJrIGl0IGFzIGxvd2VzdC4KICAgICAqIElmIGEgc2luZ2xlIHNlc3Npb24gaXMgc3BlY2lmaWVkLCBkbyBqdXN0IGZvciB0aGF0IHNlc3Npb24uCiAgICAgKi8KCiAgICBpZiAoc2Vzc3ApIHsKICAgICAgICBzbHAgPSBzbHB0ZXN0OwogICAgfSBlbHNlIHsKICAgICAgICBzbHAgPSBTZXNzaW9uczsKICAgIH0KCiAgICBERUJVR01TR1RMKCgic2Vzc19zZWxlY3QiLCAiZm9yICVzIHNlc3Npb24lczogIiwKICAgICAgICAgICAgICAgIHNlc3NwID8gInNpbmdsZSIgOiAiYWxsIiwgc2Vzc3AgPyAiIiA6ICJzIikpOwoKICAgIGZvciAoOyBzbHA7IHNscCA9IG5leHQpIHsKICAgICAgICBuZXh0ID0gc2xwLT5uZXh0OwoKICAgICAgICBpZiAoc2xwLT50cmFuc3BvcnQgPT0gTlVMTCkgewogICAgICAgICAgICAvKgogICAgICAgICAgICAgKiBDbG9zZSBpbiBwcm9ncmVzcyAtLSBza2lwIHRoaXMgb25lLiAgCiAgICAgICAgICAgICAqLwogICAgICAgICAgICBERUJVR01TRygoInNlc3Nfc2VsZWN0IiwgInNraXAgIikpOwogICAgICAgICAgICBjb250aW51ZTsKICAgICAgICB9CgogICAgICAgIGlmIChzbHAtPnRyYW5zcG9ydC0+c29jayA9PSAtMSkgewogICAgICAgICAgICAvKgogICAgICAgICAgICAgKiBUaGlzIHNlc3Npb24gd2FzIG1hcmtlZCBmb3IgZGVsZXRpb24uICAKICAgICAgICAgICAgICovCiAgICAgICAgICAgIERFQlVHTVNHKCgic2Vzc19zZWxlY3QiLCAiZGVsZXRlXG4iKSk7CiAgICAgICAgICAgIGlmIChzZXNzcCA9PSBOVUxMKSB7CiAgICAgICAgICAgICAgICBzbm1wX2Nsb3NlKHNscC0+c2Vzc2lvbik7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBzbm1wX3Nlc3NfY2xvc2Uoc2xwKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBERUJVR01TR1RMKCgic2Vzc19zZWxlY3QiLCAiZm9yICVzIHNlc3Npb24lczogIiwKICAgICAgICAgICAgICAgICAgICAgICAgc2Vzc3AgPyAic2luZ2xlIiA6ICJhbGwiLCBzZXNzcCA/ICIiIDogInMiKSk7CiAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgIH0KCiAgICAgICAgREVCVUdNU0coKCJzZXNzX3NlbGVjdCIsICIlZCAiLCBzbHAtPnRyYW5zcG9ydC0+c29jaykpOwogICAgICAgIGlmICgoc2xwLT50cmFuc3BvcnQtPnNvY2sgKyAxKSA+ICpudW1mZHMpIHsKICAgICAgICAgICAgKm51bWZkcyA9IChzbHAtPnRyYW5zcG9ydC0+c29jayArIDEpOwogICAgICAgIH0KCiAgICAgICAgRkRfU0VUKHNscC0+dHJhbnNwb3J0LT5zb2NrLCBmZHNldCk7CiAgICAgICAgaWYgKHNscC0+aW50ZXJuYWwgIT0gTlVMTCAmJiBzbHAtPmludGVybmFsLT5yZXF1ZXN0cykgewogICAgICAgICAgICAvKgogICAgICAgICAgICAgKiBGb3VuZCBhbm90aGVyIHNlc3Npb24gd2l0aCBvdXRzdGFuZGluZyByZXF1ZXN0cy4gIAogICAgICAgICAgICAgKi8KICAgICAgICAgICAgcmVxdWVzdHMrKzsKICAgICAgICAgICAgZm9yIChycCA9IHNscC0+aW50ZXJuYWwtPnJlcXVlc3RzOyBycDsgcnAgPSBycC0+bmV4dF9yZXF1ZXN0KSB7CiAgICAgICAgICAgICAgICBpZiAoKCF0aW1lcmlzc2V0KCZlYXJsaWVzdCkKICAgICAgICAgICAgICAgICAgICAgfHwgKHRpbWVyY21wKCZycC0+ZXhwaXJlLCAmZWFybGllc3QsIDwpKSkpIHsKICAgICAgICAgICAgICAgICAgICBlYXJsaWVzdCA9IHJwLT5leHBpcmU7CiAgICAgICAgICAgICAgICAgICAgREVCVUdNU0coKCJ2ZXJib3NlOnNlc3Nfc2VsZWN0IiwiKHRvIGluICVkLiVkIHNlYykgIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVhcmxpZXN0LnR2X3NlYywgZWFybGllc3QudHZfdXNlYykpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBhY3RpdmUrKzsKICAgICAgICBpZiAoc2Vzc3ApIHsKICAgICAgICAgICAgLyoKICAgICAgICAgICAgICogU2luZ2xlIHNlc3Npb24gcHJvY2Vzc2luZy4gIAogICAgICAgICAgICAgKi8KICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgfQogICAgfQogICAgREVCVUdNU0coKCJzZXNzX3NlbGVjdCIsICJcbiIpKTsKCiAgICBpZiAobmV0c25tcF9kc19nZXRfYm9vbGVhbihORVRTTk1QX0RTX0xJQlJBUllfSUQsIE5FVFNOTVBfRFNfTElCX0FMQVJNX0RPTlRfVVNFX1NJRykpIHsKICAgICAgICBuZXh0X2FsYXJtID0gZ2V0X25leHRfYWxhcm1fZGVsYXlfdGltZSgmZGVsdGEpOwogICAgICAgIERFQlVHTVNHVCgoInNlc3Nfc2VsZWN0IiwibmV4dCBhbGFybSAlZC4lZCBzZWNcbiIsCiAgICAgICAgICAgICAgICAgICBkZWx0YS50dl9zZWMsIGRlbHRhLnR2X3VzZWMpKTsKICAgIH0KICAgIGlmIChuZXh0X2FsYXJtID09IDAgJiYgcmVxdWVzdHMgPT0gMCkgewogICAgICAgIC8qCiAgICAgICAgICogSWYgbm9uZSBhcmUgYWN0aXZlLCBza2lwIGFyaXRobWV0aWMuICAKICAgICAgICAgKi8KICAgICAgICBERUJVR01TR1QoKCJzZXNzX3NlbGVjdCIsImJsb2NraW5nOm5vIHNlc3Npb24gcmVxdWVzdHMgb3IgYWxhcm1zLlxuIikpOwogICAgICAgICpibG9jayA9IDE7IC8qIGNhbiBibG9jayAtIHRpbWVvdXQgdmFsdWUgaXMgdW5kZWZpbmVkIGlmIG5vIHJlcXVlc3RzICovCiAgICAgICAgcmV0dXJuIGFjdGl2ZTsKICAgIH0KCiAgICAvKgogICAgICogKiBOb3cgZmluZCBvdXQgaG93IG11Y2ggdGltZSB1bnRpbCB0aGUgZWFybGllc3QgdGltZW91dC4gIFRoaXMKICAgICAqICogdHJhbnNmb3JtcyBlYXJsaWVzdCBmcm9tIGFuIGFic29sdXRlIHRpbWUgaW50byBhIGRlbHRhIHRpbWUsIHRoZQogICAgICogKiB0aW1lIGxlZnQgdW50aWwgdGhlIHNlbGVjdCBzaG91bGQgdGltZW91dC4KICAgICAqLwogICAgZ2V0dGltZW9mZGF5KCZub3csIChzdHJ1Y3QgdGltZXpvbmUgKikgMCk7CiAgICAvKgogICAgICogTm93ID0gbm93OwogICAgICovCgogICAgaWYgKG5leHRfYWxhcm0pIHsKICAgICAgICBkZWx0YS50dl9zZWMgKz0gbm93LnR2X3NlYzsKICAgICAgICBkZWx0YS50dl91c2VjICs9IG5vdy50dl91c2VjOwogICAgICAgIHdoaWxlIChkZWx0YS50dl91c2VjID49IDEwMDAwMDApIHsKICAgICAgICAgICAgZGVsdGEudHZfdXNlYyAtPSAxMDAwMDAwOwogICAgICAgICAgICBkZWx0YS50dl9zZWMgKz0gMTsKICAgICAgICB9CiAgICAgICAgaWYgKCF0aW1lcmlzc2V0KCZlYXJsaWVzdCkgfHwKICAgICAgICAgICAgKChlYXJsaWVzdC50dl9zZWMgPiBkZWx0YS50dl9zZWMpIHx8CiAgICAgICAgICAgICAoKGVhcmxpZXN0LnR2X3NlYyA9PSBkZWx0YS50dl9zZWMpICYmCiAgICAgICAgICAgICAgKGVhcmxpZXN0LnR2X3VzZWMgPiBkZWx0YS50dl91c2VjKSkpKSB7CiAgICAgICAgICAgIGVhcmxpZXN0LnR2X3NlYyA9IGRlbHRhLnR2X3NlYzsKICAgICAgICAgICAgZWFybGllc3QudHZfdXNlYyA9IGRlbHRhLnR2X3VzZWM7CiAgICAgICAgfQogICAgfQoKICAgIGlmIChlYXJsaWVzdC50dl9zZWMgPCBub3cudHZfc2VjKSB7CiAgICAgICAgREVCVUdNU0dUKCgidmVyYm9zZTpzZXNzX3NlbGVjdCIsInRpbWVyIG92ZXJkdWVcbiIpKTsKICAgICAgICBlYXJsaWVzdC50dl9zZWMgPSAwOwogICAgICAgIGVhcmxpZXN0LnR2X3VzZWMgPSAwOwogICAgfSBlbHNlIGlmIChlYXJsaWVzdC50dl9zZWMgPT0gbm93LnR2X3NlYykgewogICAgICAgIGVhcmxpZXN0LnR2X3NlYyA9IDA7CiAgICAgICAgZWFybGllc3QudHZfdXNlYyA9IChlYXJsaWVzdC50dl91c2VjIC0gbm93LnR2X3VzZWMpOwogICAgICAgIGlmIChlYXJsaWVzdC50dl91c2VjIDwgMCkgewogICAgICAgICAgICBlYXJsaWVzdC50dl91c2VjID0gMTAwOwogICAgICAgIH0KICAgICAgICBERUJVR01TR1QoKCJ2ZXJib3NlOnNlc3Nfc2VsZWN0IiwidGltZXIgZHVlICpyZWFsKiBzb29uLiAlZCB1c2VjXG4iLAogICAgICAgICAgICAgICAgICAgZWFybGllc3QudHZfdXNlYykpOwogICAgfSBlbHNlIHsKICAgICAgICBlYXJsaWVzdC50dl9zZWMgPSAoZWFybGllc3QudHZfc2VjIC0gbm93LnR2X3NlYyk7CiAgICAgICAgZWFybGllc3QudHZfdXNlYyA9IChlYXJsaWVzdC50dl91c2VjIC0gbm93LnR2X3VzZWMpOwogICAgICAgIGlmIChlYXJsaWVzdC50dl91c2VjIDwgMCkgewogICAgICAgICAgICBlYXJsaWVzdC50dl9zZWMtLTsKICAgICAgICAgICAgZWFybGllc3QudHZfdXNlYyA9ICgxMDAwMDAwTCArIGVhcmxpZXN0LnR2X3VzZWMpOwogICAgICAgIH0KICAgICAgICBERUJVR01TR1QoKCJ2ZXJib3NlOnNlc3Nfc2VsZWN0IiwidGltZXIgZHVlIGluICVkLiVkIHNlY1xuIiwKICAgICAgICAgICAgICAgICAgIGVhcmxpZXN0LnR2X3NlYywgZWFybGllc3QudHZfdXNlYykpOwogICAgfQoKICAgIC8qCiAgICAgKiBpZiBpdCB3YXMgYmxvY2tpbmcgYmVmb3JlIG9yIG91ciBkZWx0YSB0aW1lIGlzIGxlc3MsIHJlc2V0IHRpbWVvdXQgCiAgICAgKi8KICAgIGlmICgoKmJsb2NrIHx8ICh0aW1lcmNtcCgmZWFybGllc3QsIHRpbWVvdXQsIDwpKSkpIHsKICAgICAgICBERUJVR01TR1QoKCJ2ZXJib3NlOnNlc3Nfc2VsZWN0IiwKICAgICAgICAgICAgICAgICAgICJzZXR0aW5nIHRpbWVyIHRvICVkLiVkIHNlYywgY2xlYXIgYmxvY2sgKHdhcyAlZClcbiIsCiAgICAgICAgICAgICAgICAgICBlYXJsaWVzdC50dl9zZWMsIGVhcmxpZXN0LnR2X3VzZWMsICpibG9jaykpOwogICAgICAgICp0aW1lb3V0ID0gZWFybGllc3Q7CiAgICAgICAgKmJsb2NrID0gMDsKICAgIH0KICAgIHJldHVybiBhY3RpdmU7Cn0KCi8qCiAqIHNubXBfdGltZW91dCBzaG91bGQgYmUgY2FsbGVkIHdoZW5ldmVyIHRoZSB0aW1lb3V0IGZyb20gc25tcF9zZWxlY3RfaW5mbwogKiBleHBpcmVzLCBidXQgaXQgaXMgaWRlbXBvdGVudCwgc28gc25tcF90aW1lb3V0IGNhbiBiZSBwb2xsZWQgKHByb2JhYmx5IGEKICogY3B1IGV4cGVuc2l2ZSBwcm9wb3NpdGlvbikuICBzbm1wX3RpbWVvdXQgY2hlY2tzIHRvIHNlZSBpZiBhbnkgb2YgdGhlCiAqIHNlc3Npb25zIGhhdmUgYW4gb3V0c3RhbmRpbmcgcmVxdWVzdCB0aGF0IGhhcyB0aW1lZCBvdXQuICBJZiBpdCBmaW5kcyBvbmUKICogKG9yIG1vcmUpLCBhbmQgdGhhdCBwZHUgaGFzIG1vcmUgcmV0cmllcyBhdmFpbGFibGUsIGEgbmV3IHBhY2tldCBpcyBmb3JtZWQKICogZnJvbSB0aGUgcGR1IGFuZCBpcyByZXNlbnQuICBJZiB0aGVyZSBhcmUgbm8gbW9yZSByZXRyaWVzIGF2YWlsYWJsZSwgdGhlCiAqICBjYWxsYmFjayBmb3IgdGhlIHNlc3Npb24gaXMgdXNlZCB0byBhbGVydCB0aGUgdXNlciBvZiB0aGUgdGltZW91dC4KICovCnZvaWQKc25tcF90aW1lb3V0KHZvaWQpCnsKICAgIHN0cnVjdCBzZXNzaW9uX2xpc3QgKnNscDsKICAgIHNubXBfcmVzX2xvY2soTVRfTElCUkFSWV9JRCwgTVRfTElCX1NFU1NJT04pOwogICAgZm9yIChzbHAgPSBTZXNzaW9uczsgc2xwOyBzbHAgPSBzbHAtPm5leHQpIHsKICAgICAgICBzbm1wX3Nlc3NfdGltZW91dCgodm9pZCAqKSBzbHApOwogICAgfQogICAgc25tcF9yZXNfdW5sb2NrKE1UX0xJQlJBUllfSUQsIE1UX0xJQl9TRVNTSU9OKTsKfQoKc3RhdGljIGludApzbm1wX3Jlc2VuZF9yZXF1ZXN0KHN0cnVjdCBzZXNzaW9uX2xpc3QgKnNscCwgbmV0c25tcF9yZXF1ZXN0X2xpc3QgKnJwLAogICAgICAgICAgICAgICAgICAgIGludCBpbmNyX3JldHJpZXMpCnsKICAgIHN0cnVjdCBzbm1wX2ludGVybmFsX3Nlc3Npb24gKmlzcDsKICAgIG5ldHNubXBfc2Vzc2lvbiAqc3A7CiAgICBuZXRzbm1wX3RyYW5zcG9ydCAqdHJhbnNwb3J0OwogICAgdV9jaGFyICAgICAgICAgKnBrdGJ1ZiA9IE5VTEwsICpwYWNrZXQgPSBOVUxMOwogICAgc2l6ZV90ICAgICAgICAgIHBrdGJ1Zl9sZW4gPSAwLCBvZmZzZXQgPSAwLCBsZW5ndGggPSAwOwogICAgc3RydWN0IHRpbWV2YWwgIHR2LCBub3c7CiAgICBpbnQgICAgICAgICAgICAgcmVzdWx0ID0gMDsKCiAgICBzcCA9IHNscC0+c2Vzc2lvbjsKICAgIGlzcCA9IHNscC0+aW50ZXJuYWw7CiAgICB0cmFuc3BvcnQgPSBzbHAtPnRyYW5zcG9ydDsKICAgIGlmICghc3AgfHwgIWlzcCB8fCAhdHJhbnNwb3J0KSB7CiAgICAgICAgREVCVUdNU0dUTCgoInNlc3NfcmVhZCIsICJyZXNlbmQgZmFpbDogY2xvc2luZy4uLlxuIikpOwogICAgICAgIHJldHVybiAwOwogICAgfQoKICAgIGlmICgocGt0YnVmID0gKHVfY2hhciAqKW1hbGxvYygyMDQ4KSkgPT0gTlVMTCkgewogICAgICAgIERFQlVHTVNHVEwoKCJzZXNzX3Jlc2VuZCIsCiAgICAgICAgICAgICAgICAgICAgImNvdWxkbid0IG1hbGxvYyBpbml0aWFsIHBhY2tldCBidWZmZXJcbiIpKTsKICAgICAgICByZXR1cm4gMDsKICAgIH0gZWxzZSB7CiAgICAgICAgcGt0YnVmX2xlbiA9IDIwNDg7CiAgICB9CgogICAgaWYgKGluY3JfcmV0cmllcykgewogICAgICAgIHJwLT5yZXRyaWVzKys7CiAgICB9CgogICAgLyoKICAgICAqIEFsd2F5cyBpbmNyZW1lbnQgbXNnSWQgZm9yIHJlc2VudCBtZXNzYWdlcy4gIAogICAgICovCiAgICBycC0+cGR1LT5tc2dpZCA9IHJwLT5tZXNzYWdlX2lkID0gc25tcF9nZXRfbmV4dF9tc2dpZCgpOwoKICAgIGlmIChpc3AtPmhvb2tfcmVhbGxvY19idWlsZCkgewogICAgICAgIHJlc3VsdCA9IGlzcC0+aG9va19yZWFsbG9jX2J1aWxkKHNwLCBycC0+cGR1LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZwa3RidWYsICZwa3RidWZfbGVuLCAmb2Zmc2V0KTsKCiAgICAgICAgcGFja2V0ID0gcGt0YnVmOwogICAgICAgIGxlbmd0aCA9IG9mZnNldDsKICAgIH0gZWxzZSBpZiAoaXNwLT5ob29rX2J1aWxkKSB7CiAgICAgICAgcGFja2V0ID0gcGt0YnVmOwogICAgICAgIGxlbmd0aCA9IHBrdGJ1Zl9sZW47CiAgICAgICAgcmVzdWx0ID0gaXNwLT5ob29rX2J1aWxkKHNwLCBycC0+cGR1LCBwa3RidWYsICZsZW5ndGgpOwogICAgfSBlbHNlIHsKI2lmZGVmIE5FVFNOTVBfVVNFX1JFVkVSU0VfQVNORU5DT0RJTkcKICAgICAgICBpZiAobmV0c25tcF9kc19nZXRfYm9vbGVhbihORVRTTk1QX0RTX0xJQlJBUllfSUQsIE5FVFNOTVBfRFNfTElCX1JFVkVSU0VfRU5DT0RFKSkgewogICAgICAgICAgICByZXN1bHQgPQogICAgICAgICAgICAgICAgc25tcF9idWlsZCgmcGt0YnVmLCAmcGt0YnVmX2xlbiwgJm9mZnNldCwgc3AsIHJwLT5wZHUpOwogICAgICAgICAgICBwYWNrZXQgPSBwa3RidWYgKyBwa3RidWZfbGVuIC0gb2Zmc2V0OwogICAgICAgICAgICBsZW5ndGggPSBvZmZzZXQ7CiAgICAgICAgfSBlbHNlIHsKI2VuZGlmCiAgICAgICAgICAgIHBhY2tldCA9IHBrdGJ1ZjsKICAgICAgICAgICAgbGVuZ3RoID0gcGt0YnVmX2xlbjsKICAgICAgICAgICAgcmVzdWx0ID0gc25tcF9idWlsZCgmcGt0YnVmLCAmbGVuZ3RoLCAmb2Zmc2V0LCBzcCwgcnAtPnBkdSk7CiNpZmRlZiBORVRTTk1QX1VTRV9SRVZFUlNFX0FTTkVOQ09ESU5HCiAgICAgICAgfQojZW5kaWYKICAgIH0KCiAgICBpZiAocmVzdWx0IDwgMCkgewogICAgICAgIC8qCiAgICAgICAgICogVGhpcyBzaG91bGQgbmV2ZXIgaGFwcGVuLiAgCiAgICAgICAgICovCiAgICAgICAgREVCVUdNU0dUTCgoInNlc3NfcmVzZW5kIiwgImVuY29kaW5nIGZhaWx1cmVcbiIpKTsKICAgICAgICBpZiAocGt0YnVmICE9IE5VTEwpIHsKICAgICAgICAgICAgU05NUF9GUkVFKHBrdGJ1Zik7CiAgICAgICAgfQogICAgICAgIHJldHVybiAtMTsKICAgIH0KCiAgICBpZiAobmV0c25tcF9kc19nZXRfYm9vbGVhbihORVRTTk1QX0RTX0xJQlJBUllfSUQsIE5FVFNOTVBfRFNfTElCX0RVTVBfUEFDS0VUKSkgewogICAgICAgIGlmICh0cmFuc3BvcnQtPmZfZm10YWRkciAhPSBOVUxMKSB7CiAgICAgICAgICAgIGNoYXIgICAgICAgICAgICpzdHIgPSBOVUxMOwogICAgICAgICAgICBzdHIgPSB0cmFuc3BvcnQtPmZfZm10YWRkcih0cmFuc3BvcnQsIHJwLT5wZHUtPnRyYW5zcG9ydF9kYXRhLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBycC0+cGR1LT50cmFuc3BvcnRfZGF0YV9sZW5ndGgpOwogICAgICAgICAgICBpZiAoc3RyICE9IE5VTEwpIHsKICAgICAgICAgICAgICAgIHNubXBfbG9nKExPR19ERUJVRywgIlxuUmVzZW5kaW5nICVsdSBieXRlcyB0byAlc1xuIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAodW5zaWduZWQgbG9uZylsZW5ndGgsIHN0cik7CiAgICAgICAgICAgICAgICBTTk1QX0ZSRUUoc3RyKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIHNubXBfbG9nKExPR19ERUJVRywgIlxuUmVzZW5kaW5nICVsdSBieXRlcyB0byA8VU5LTk9XTj5cbiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAodW5zaWduZWQgbG9uZylsZW5ndGgpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHhkdW1wKHBhY2tldCwgbGVuZ3RoLCAiIik7CiAgICB9CgogICAgcmVzdWx0ID0gdHJhbnNwb3J0LT5mX3NlbmQodHJhbnNwb3J0LCBwYWNrZXQsIGxlbmd0aCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICYocnAtPnBkdS0+dHJhbnNwb3J0X2RhdGEpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJihycC0+cGR1LT50cmFuc3BvcnRfZGF0YV9sZW5ndGgpKTsKCiAgICAvKgogICAgICogV2UgYXJlIGZpbmlzaGVkIHdpdGggdGhlIGxvY2FsIHBhY2tldCBidWZmZXIsIGlmIHdlIGFsbG9jYXRlZCBvbmUgKGR1ZQogICAgICogdG8gdGhlcmUgYmVpbmcgbm8gc2F2ZWQgcGFja2V0KS4gIAogICAgICovCgogICAgaWYgKHBrdGJ1ZiAhPSBOVUxMKSB7CiAgICAgICAgU05NUF9GUkVFKHBrdGJ1Zik7CiAgICAgICAgcGt0YnVmID0gcGFja2V0ID0gTlVMTDsKICAgIH0KCiAgICBpZiAocmVzdWx0IDwgMCkgewogICAgICAgIHNwLT5zX3NubXBfZXJybm8gPSBTTk1QRVJSX0JBRF9TRU5EVE87CiAgICAgICAgc3AtPnNfZXJybm8gPSBlcnJubzsKICAgICAgICBzbm1wX3NldF9kZXRhaWwoc3RyZXJyb3IoZXJybm8pKTsKICAgICAgICByZXR1cm4gLTE7CiAgICB9IGVsc2UgewogICAgICAgIGdldHRpbWVvZmRheSgmbm93LCAoc3RydWN0IHRpbWV6b25lICopIDApOwogICAgICAgIHR2ID0gbm93OwogICAgICAgIHJwLT50aW1lID0gdHY7CiAgICAgICAgdHYudHZfdXNlYyArPSBycC0+dGltZW91dDsKICAgICAgICB0di50dl9zZWMgKz0gdHYudHZfdXNlYyAvIDEwMDAwMDBMOwogICAgICAgIHR2LnR2X3VzZWMgJT0gMTAwMDAwMEw7CiAgICAgICAgcnAtPmV4cGlyZSA9IHR2OwogICAgfQogICAgcmV0dXJuIDA7Cn0KCgoKdm9pZApzbm1wX3Nlc3NfdGltZW91dCh2b2lkICpzZXNzcCkKewogICAgc3RydWN0IHNlc3Npb25fbGlzdCAqc2xwID0gKHN0cnVjdCBzZXNzaW9uX2xpc3QgKikgc2Vzc3A7CiAgICBuZXRzbm1wX3Nlc3Npb24gKnNwOwogICAgc3RydWN0IHNubXBfaW50ZXJuYWxfc2Vzc2lvbiAqaXNwOwogICAgbmV0c25tcF9yZXF1ZXN0X2xpc3QgKnJwLCAqb3JwID0gTlVMTCwgKmZyZWVtZSA9IE5VTEw7CiAgICBzdHJ1Y3QgdGltZXZhbCAgbm93OwogICAgc25tcF9jYWxsYmFjayAgIGNhbGxiYWNrOwogICAgdm9pZCAgICAgICAgICAgKm1hZ2ljOwogICAgc3RydWN0IHNubXBfc2VjbW9kX2RlZiAqc3B0cjsKCiAgICBzcCA9IHNscC0+c2Vzc2lvbjsKICAgIGlzcCA9IHNscC0+aW50ZXJuYWw7CiAgICBpZiAoIXNwIHx8ICFpc3ApIHsKICAgICAgICBERUJVR01TR1RMKCgic2Vzc19yZWFkIiwgInRpbWVvdXQgZmFpbDogY2xvc2luZy4uLlxuIikpOwogICAgICAgIHJldHVybjsKICAgIH0KCiAgICBnZXR0aW1lb2ZkYXkoJm5vdywgKHN0cnVjdCB0aW1lem9uZSAqKSAwKTsKCiAgICAvKgogICAgICogRm9yIGVhY2ggcmVxdWVzdCBvdXRzdGFuZGluZywgY2hlY2sgdG8gc2VlIGlmIGl0IGhhcyBleHBpcmVkLgogICAgICovCiAgICBmb3IgKHJwID0gaXNwLT5yZXF1ZXN0czsgcnA7IHJwID0gcnAtPm5leHRfcmVxdWVzdCkgewogICAgICAgIGlmIChmcmVlbWUgIT0gTlVMTCkgewogICAgICAgICAgICAvKgogICAgICAgICAgICAgKiBmcmVlcyBycCdzIGFmdGVyIHRoZSBmb3IgbG9vcCBnb2VzIG9uIHRvIHRoZSBuZXh0X3JlcXVlc3QgCiAgICAgICAgICAgICAqLwogICAgICAgICAgICBmcmVlKChjaGFyICopIGZyZWVtZSk7CiAgICAgICAgICAgIGZyZWVtZSA9IE5VTEw7CiAgICAgICAgfQoKICAgICAgICBpZiAoKHRpbWVyY21wKCZycC0+ZXhwaXJlLCAmbm93LCA8KSkpIHsKICAgICAgICAgICAgaWYgKChzcHRyID0gZmluZF9zZWNfbW9kKHJwLT5wZHUtPnNlY3VyaXR5TW9kZWwpKSAhPSBOVUxMICYmCiAgICAgICAgICAgICAgICBzcHRyLT5wZHVfdGltZW91dCAhPSBOVUxMKSB7CiAgICAgICAgICAgICAgICAvKgogICAgICAgICAgICAgICAgICogY2FsbCBzZWN1cml0eSBtb2RlbCBpZiBpdCBuZWVkcyB0byBrbm93IGFib3V0IHRoaXMgCiAgICAgICAgICAgICAgICAgKi8KICAgICAgICAgICAgICAgICgqc3B0ci0+cGR1X3RpbWVvdXQpIChycC0+cGR1KTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgLyoKICAgICAgICAgICAgICogdGhpcyB0aW1lciBoYXMgZXhwaXJlZCAKICAgICAgICAgICAgICovCiAgICAgICAgICAgIGlmIChycC0+cmV0cmllcyA+PSBzcC0+cmV0cmllcykgewogICAgICAgICAgICAgICAgaWYgKHJwLT5jYWxsYmFjaykgewogICAgICAgICAgICAgICAgICAgIGNhbGxiYWNrID0gcnAtPmNhbGxiYWNrOwogICAgICAgICAgICAgICAgICAgIG1hZ2ljID0gcnAtPmNiX2RhdGE7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIGNhbGxiYWNrID0gc3AtPmNhbGxiYWNrOwogICAgICAgICAgICAgICAgICAgIG1hZ2ljID0gc3AtPmNhbGxiYWNrX21hZ2ljOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAgICAgKiBObyBtb3JlIGNoYW5jZXMsIGRlbGV0ZSB0aGlzIGVudHJ5IAogICAgICAgICAgICAgICAgICovCiAgICAgICAgICAgICAgICBpZiAoY2FsbGJhY2spIHsKICAgICAgICAgICAgICAgICAgICBjYWxsYmFjayhORVRTTk1QX0NBTExCQUNLX09QX1RJTUVEX09VVCwgc3AsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcnAtPnBkdS0+cmVxaWQsIHJwLT5wZHUsIG1hZ2ljKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlmIChpc3AtPnJlcXVlc3RzID09IHJwKSB7CiAgICAgICAgICAgICAgICAgICAgaXNwLT5yZXF1ZXN0cyA9IHJwLT5uZXh0X3JlcXVlc3Q7CiAgICAgICAgICAgICAgICAgICAgaWYgKGlzcC0+cmVxdWVzdHNFbmQgPT0gcnApIHsKICAgICAgICAgICAgICAgICAgICAgICAgaXNwLT5yZXF1ZXN0c0VuZCA9IE5VTEw7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICBvcnAtPm5leHRfcmVxdWVzdCA9IHJwLT5uZXh0X3JlcXVlc3Q7CiAgICAgICAgICAgICAgICAgICAgaWYgKGlzcC0+cmVxdWVzdHNFbmQgPT0gcnApIHsKICAgICAgICAgICAgICAgICAgICAgICAgaXNwLT5yZXF1ZXN0c0VuZCA9IG9ycDsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBzbm1wX2ZyZWVfcGR1KHJwLT5wZHUpOyAvKiBGSVggIHJwIGlzIGFscmVhZHkgZnJlZSdkISAqLwogICAgICAgICAgICAgICAgZnJlZW1lID0gcnA7CiAgICAgICAgICAgICAgICBjb250aW51ZTsgICAgICAgLyogZG9uJ3QgdXBkYXRlIG9ycCBiZWxvdyAqLwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgaWYgKHNubXBfcmVzZW5kX3JlcXVlc3Qoc2xwLCBycCwgVFJVRSkpIHsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBvcnAgPSBycDsKICAgIH0KCiAgICBpZiAoZnJlZW1lICE9IE5VTEwpIHsKICAgICAgICBmcmVlKChjaGFyICopIGZyZWVtZSk7CiAgICAgICAgZnJlZW1lID0gTlVMTDsKICAgIH0KfQoKLyoKICogbGV4aWNvZ3JhcGhpY2FsIGNvbXBhcmUgdHdvIG9iamVjdCBpZGVudGlmaWVycy4KICogKiBSZXR1cm5zIC0xIGlmIG5hbWUxIDwgbmFtZTIsCiAqICogICAgICAgICAgMCBpZiBuYW1lMSA9IG5hbWUyLAogKiAqICAgICAgICAgIDEgaWYgbmFtZTEgPiBuYW1lMgogKiAqCiAqICogQ2F1dGlvbjogdGhpcyBtZXRob2QgaXMgY2FsbGVkIG9mdGVuIGJ5CiAqICogICAgICAgICAgY29tbWFuZCByZXNwb25kZXIgYXBwbGljYXRpb25zIChpZSwgYWdlbnQpLgogKi8KaW50CnNubXBfb2lkX25jb21wYXJlKGNvbnN0IG9pZCAqIGluX25hbWUxLAogICAgICAgICAgICAgICAgICBzaXplX3QgbGVuMSwKICAgICAgICAgICAgICAgICAgY29uc3Qgb2lkICogaW5fbmFtZTIsIHNpemVfdCBsZW4yLCBzaXplX3QgbWF4X2xlbikKewogICAgcmVnaXN0ZXIgaW50ICAgIGxlbjsKICAgIHJlZ2lzdGVyIGNvbnN0IG9pZCAqbmFtZTEgPSBpbl9uYW1lMTsKICAgIHJlZ2lzdGVyIGNvbnN0IG9pZCAqbmFtZTIgPSBpbl9uYW1lMjsKICAgIHNpemVfdCAgICAgICAgICBtaW5fbGVuOwoKICAgIC8qCiAgICAgKiBsZW4gPSBtaW5pbXVtIG9mIGxlbjEgYW5kIGxlbjIgCiAgICAgKi8KICAgIGlmIChsZW4xIDwgbGVuMikKICAgICAgICBtaW5fbGVuID0gbGVuMTsKICAgIGVsc2UKICAgICAgICBtaW5fbGVuID0gbGVuMjsKCiAgICBpZiAobWluX2xlbiA+IG1heF9sZW4pCiAgICAgICAgbWluX2xlbiA9IG1heF9sZW47CgogICAgbGVuID0gbWluX2xlbjsKCiAgICAvKgogICAgICogZmluZCBmaXJzdCBub24tbWF0Y2hpbmcgT0lEIAogICAgICovCiAgICB3aGlsZSAobGVuLS0gPiAwKSB7CiAgICAgICAgLyoKICAgICAgICAgKiB0aGVzZSBtdXN0IGJlIGRvbmUgaW4gc2VwZXJhdGUgY29tcGFyaXNvbnMsIHNpbmNlCiAgICAgICAgICogc3VidHJhY3RpbmcgdGhlbSBhbmQgdXNpbmcgdGhhdCByZXN1bHQgaGFzIHByb2JsZW1zIHdpdGgKICAgICAgICAgKiBzdWJpZHMgPiAyXjMxLiAKICAgICAgICAgKi8KICAgICAgICBpZiAoKihuYW1lMSkgIT0gKihuYW1lMikpIHsKICAgICAgICAgICAgaWYgKCoobmFtZTEpIDwgKihuYW1lMikpCiAgICAgICAgICAgICAgICByZXR1cm4gLTE7CiAgICAgICAgICAgIHJldHVybiAxOwogICAgICAgIH0KICAgICAgICBuYW1lMSsrOwogICAgICAgIG5hbWUyKys7CiAgICB9CgogICAgaWYgKG1pbl9sZW4gIT0gbWF4X2xlbikgewogICAgICAgIC8qCiAgICAgICAgICogYm90aCBPSURzIGVxdWFsIHVwIHRvIGxlbmd0aCBvZiBzaG9ydGVyIE9JRCAKICAgICAgICAgKi8KICAgICAgICBpZiAobGVuMSA8IGxlbjIpCiAgICAgICAgICAgIHJldHVybiAtMTsKICAgICAgICBpZiAobGVuMiA8IGxlbjEpCiAgICAgICAgICAgIHJldHVybiAxOwogICAgfQoKICAgIHJldHVybiAwOwp9CgovKiogbGV4aWNvZ3JhcGhpY2FsIGNvbXBhcmUgdHdvIG9iamVjdCBpZGVudGlmaWVycy4KICogCiAqIENhdXRpb246IHRoaXMgbWV0aG9kIGlzIGNhbGxlZCBvZnRlbiBieQogKiAgICAgICAgICBjb21tYW5kIHJlc3BvbmRlciBhcHBsaWNhdGlvbnMgKGllLCBhZ2VudCkuCiAqCiAqIEByZXR1cm4gLTEgaWYgbmFtZTEgPCBuYW1lMiwgMCBpZiBuYW1lMSA9IG5hbWUyLCAxIGlmIG5hbWUxID4gbmFtZTIKICovCmludApzbm1wX29pZF9jb21wYXJlKGNvbnN0IG9pZCAqIGluX25hbWUxLAogICAgICAgICAgICAgICAgIHNpemVfdCBsZW4xLCBjb25zdCBvaWQgKiBpbl9uYW1lMiwgc2l6ZV90IGxlbjIpCnsKICAgIHJlZ2lzdGVyIGludCAgICBsZW47CiAgICByZWdpc3RlciBjb25zdCBvaWQgKm5hbWUxID0gaW5fbmFtZTE7CiAgICByZWdpc3RlciBjb25zdCBvaWQgKm5hbWUyID0gaW5fbmFtZTI7CgogICAgLyoKICAgICAqIGxlbiA9IG1pbmltdW0gb2YgbGVuMSBhbmQgbGVuMiAKICAgICAqLwogICAgaWYgKGxlbjEgPCBsZW4yKQogICAgICAgIGxlbiA9IGxlbjE7CiAgICBlbHNlCiAgICAgICAgbGVuID0gbGVuMjsKICAgIC8qCiAgICAgKiBmaW5kIGZpcnN0IG5vbi1tYXRjaGluZyBPSUQgCiAgICAgKi8KICAgIHdoaWxlIChsZW4tLSA+IDApIHsKICAgICAgICAvKgogICAgICAgICAqIHRoZXNlIG11c3QgYmUgZG9uZSBpbiBzZXBlcmF0ZSBjb21wYXJpc29ucywgc2luY2UKICAgICAgICAgKiBzdWJ0cmFjdGluZyB0aGVtIGFuZCB1c2luZyB0aGF0IHJlc3VsdCBoYXMgcHJvYmxlbXMgd2l0aAogICAgICAgICAqIHN1YmlkcyA+IDJeMzEuIAogICAgICAgICAqLwogICAgICAgIGlmICgqKG5hbWUxKSAhPSAqKG5hbWUyKSkgewogICAgICAgICAgICBpZiAoKihuYW1lMSkgPCAqKG5hbWUyKSkKICAgICAgICAgICAgICAgIHJldHVybiAtMTsKICAgICAgICAgICAgcmV0dXJuIDE7CiAgICAgICAgfQogICAgICAgIG5hbWUxKys7CiAgICAgICAgbmFtZTIrKzsKICAgIH0KICAgIC8qCiAgICAgKiBib3RoIE9JRHMgZXF1YWwgdXAgdG8gbGVuZ3RoIG9mIHNob3J0ZXIgT0lEIAogICAgICovCiAgICBpZiAobGVuMSA8IGxlbjIpCiAgICAgICAgcmV0dXJuIC0xOwogICAgaWYgKGxlbjIgPCBsZW4xKQogICAgICAgIHJldHVybiAxOwogICAgcmV0dXJuIDA7Cn0KCi8qKiBsZXhpY29ncmFwaGljYWwgY29tcGFyZSB0d28gb2JqZWN0IGlkZW50aWZpZXJzIGFuZCByZXR1cm4gdGhlIHBvaW50IHdoZXJlIHRoZXkgZGlmZmVyCiAqIAogKiBDYXV0aW9uOiB0aGlzIG1ldGhvZCBpcyBjYWxsZWQgb2Z0ZW4gYnkKICogICAgICAgICAgY29tbWFuZCByZXNwb25kZXIgYXBwbGljYXRpb25zIChpZSwgYWdlbnQpLgogKgogKiBAcmV0dXJuIC0xIGlmIG5hbWUxIDwgbmFtZTIsIDAgaWYgbmFtZTEgPSBuYW1lMiwgMSBpZiBuYW1lMSA+IG5hbWUyIGFuZCBvZmZwdCA9IGxlbiB3aGVyZSBuYW1lMSAhPSBuYW1lMgogKi8KaW50Cm5ldHNubXBfb2lkX2NvbXBhcmVfbGwoY29uc3Qgb2lkICogaW5fbmFtZTEsCiAgICAgICAgICAgICAgICAgICAgICAgc2l6ZV90IGxlbjEsIGNvbnN0IG9pZCAqIGluX25hbWUyLCBzaXplX3QgbGVuMiwKICAgICAgICAgICAgICAgICAgICAgICBzaXplX3QgKm9mZnB0KQp7CiAgICByZWdpc3RlciBpbnQgICAgbGVuOwogICAgcmVnaXN0ZXIgY29uc3Qgb2lkICpuYW1lMSA9IGluX25hbWUxOwogICAgcmVnaXN0ZXIgY29uc3Qgb2lkICpuYW1lMiA9IGluX25hbWUyOwogICAgaW50IGluaXRsZW47CgogICAgLyoKICAgICAqIGxlbiA9IG1pbmltdW0gb2YgbGVuMSBhbmQgbGVuMiAKICAgICAqLwogICAgaWYgKGxlbjEgPCBsZW4yKQogICAgICAgIGluaXRsZW4gPSBsZW4gPSBsZW4xOwogICAgZWxzZQogICAgICAgIGluaXRsZW4gPSBsZW4gPSBsZW4yOwogICAgLyoKICAgICAqIGZpbmQgZmlyc3Qgbm9uLW1hdGNoaW5nIE9JRCAKICAgICAqLwogICAgd2hpbGUgKGxlbi0tID4gMCkgewogICAgICAgIC8qCiAgICAgICAgICogdGhlc2UgbXVzdCBiZSBkb25lIGluIHNlcGVyYXRlIGNvbXBhcmlzb25zLCBzaW5jZQogICAgICAgICAqIHN1YnRyYWN0aW5nIHRoZW0gYW5kIHVzaW5nIHRoYXQgcmVzdWx0IGhhcyBwcm9ibGVtcyB3aXRoCiAgICAgICAgICogc3ViaWRzID4gMl4zMS4gCiAgICAgICAgICovCiAgICAgICAgaWYgKCoobmFtZTEpICE9ICoobmFtZTIpKSB7CiAgICAgICAgICAgICpvZmZwdCA9IGluaXRsZW4gLSBsZW47CiAgICAgICAgICAgIGlmICgqKG5hbWUxKSA8ICoobmFtZTIpKQogICAgICAgICAgICAgICAgcmV0dXJuIC0xOwogICAgICAgICAgICByZXR1cm4gMTsKICAgICAgICB9CiAgICAgICAgbmFtZTErKzsKICAgICAgICBuYW1lMisrOwogICAgfQogICAgLyoKICAgICAqIGJvdGggT0lEcyBlcXVhbCB1cCB0byBsZW5ndGggb2Ygc2hvcnRlciBPSUQgCiAgICAgKi8KICAgICpvZmZwdCA9IGluaXRsZW4gLSBsZW47CiAgICBpZiAobGVuMSA8IGxlbjIpCiAgICAgICAgcmV0dXJuIC0xOwogICAgaWYgKGxlbjIgPCBsZW4xKQogICAgICAgIHJldHVybiAxOwogICAgcmV0dXJuIDA7Cn0KCi8qKiBDb21wYXJlcyAyIE9JRHMgdG8gZGV0ZXJtaW5lIGlmIHRoZXkgYXJlIGVxdWFsIHVwIHVudGlsIHRoZSBzaG9ydGVzdCBsZW5ndGguCiAqIEBwYXJhbSBpbl9uYW1lMSBBIHBvaW50ZXIgdG8gdGhlIGZpcnN0IG9pZC4KICogQHBhcmFtIGxlbjEgICAgIGxlbmd0aCBvZiB0aGUgZmlyc3QgT0lEIChpbiBzZWdtZW50cywgbm90IGJ5dGVzKQogKiBAcGFyYW0gaW5fbmFtZTIgQSBwb2ludGVyIHRvIHRoZSBzZWNvbmQgb2lkLgogKiBAcGFyYW0gbGVuMiAgICAgbGVuZ3RoIG9mIHRoZSBzZWNvbmQgT0lEIChpbiBzZWdtZW50cywgbm90IGJ5dGVzKQogKiBAcmV0dXJuIDAgaWYgdGhleSBhcmUgZXF1YWwsIDEgaWYgaW5fbmFtZTEgaXMgPiBpbl9uYW1lMiwgb3IgLTEgaWYgPC4KICovIAppbnQKc25tcF9vaWR0cmVlX2NvbXBhcmUoY29uc3Qgb2lkICogaW5fbmFtZTEsCiAgICAgICAgICAgICAgICAgICAgIHNpemVfdCBsZW4xLCBjb25zdCBvaWQgKiBpbl9uYW1lMiwgc2l6ZV90IGxlbjIpCnsKICAgIGludCAgICAgICAgICAgICBsZW4gPSAoKGxlbjEgPCBsZW4yKSA/IGxlbjEgOiBsZW4yKTsKCiAgICByZXR1cm4gKHNubXBfb2lkX2NvbXBhcmUoaW5fbmFtZTEsIGxlbiwgaW5fbmFtZTIsIGxlbikpOwp9CgppbnQKc25tcF9vaWRzdWJ0cmVlX2NvbXBhcmUoY29uc3Qgb2lkICogaW5fbmFtZTEsCiAgICAgICAgICAgICAgICAgICAgIHNpemVfdCBsZW4xLCBjb25zdCBvaWQgKiBpbl9uYW1lMiwgc2l6ZV90IGxlbjIpCnsKICAgIGludCAgICAgICAgICAgICBsZW4gPSAoKGxlbjEgPCBsZW4yKSA/IGxlbjEgOiBsZW4yKTsKCiAgICByZXR1cm4gKHNubXBfb2lkX2NvbXBhcmUoaW5fbmFtZTEsIGxlbjEsIGluX25hbWUyLCBsZW4pKTsKfQoKLyoqIENvbXBhcmVzIDIgT0lEcyB0byBkZXRlcm1pbmUgaWYgdGhleSBhcmUgZXhhY3RseSBlcXVhbC4KICogIFRoaXMgc2hvdWxkIGJlIGZhc3RlciB0aGFuIGRvaW5nIGEgc25tcF9vaWRfY29tcGFyZSBmb3IgZGlmZmVyZW50CiAqICBsZW5ndGggT0lEcywgc2luY2UgdGhlIGxlbmd0aCBpcyBjaGVja2VkIGZpcnN0IGFuZCBpZiAhPSByZXR1cm5zCiAqICBpbW1lZGlhdGVseS4gIE1pZ2h0IGJlIHZlcnkgc2xpZ2hseSBmYXN0ZXIgaWYgbGVuZ3RocyBhcmUgPT0uCiAqIEBwYXJhbSBpbl9uYW1lMSBBIHBvaW50ZXIgdG8gdGhlIGZpcnN0IG9pZC4KICogQHBhcmFtIGxlbjEgICAgIGxlbmd0aCBvZiB0aGUgZmlyc3QgT0lEIChpbiBzZWdtZW50cywgbm90IGJ5dGVzKQogKiBAcGFyYW0gaW5fbmFtZTIgQSBwb2ludGVyIHRvIHRoZSBzZWNvbmQgb2lkLgogKiBAcGFyYW0gbGVuMiAgICAgbGVuZ3RoIG9mIHRoZSBzZWNvbmQgT0lEIChpbiBzZWdtZW50cywgbm90IGJ5dGVzKQogKiBAcmV0dXJuIDAgaWYgdGhleSBhcmUgZXF1YWwsIDEgaWYgdGhleSBhcmUgbm90LgogKi8gCmludApuZXRzbm1wX29pZF9lcXVhbHMoY29uc3Qgb2lkICogaW5fbmFtZTEsCiAgICAgICAgICAgICAgICAgICBzaXplX3QgbGVuMSwgY29uc3Qgb2lkICogaW5fbmFtZTIsIHNpemVfdCBsZW4yKQp7CiAgICByZWdpc3RlciBjb25zdCBvaWQgKm5hbWUxID0gaW5fbmFtZTE7CiAgICByZWdpc3RlciBjb25zdCBvaWQgKm5hbWUyID0gaW5fbmFtZTI7CiAgICByZWdpc3RlciBpbnQgICAgbGVuID0gbGVuMTsKCiAgICAvKgogICAgICogbGVuID0gbWluaW11bSBvZiBsZW4xIGFuZCBsZW4yIAogICAgICovCiAgICBpZiAobGVuMSAhPSBsZW4yKQogICAgICAgIHJldHVybiAxOwogICAgLyoKICAgICAqIEhhbmRsZSAnbnVsbCcgT0lEcwogICAgICovCiAgICBpZiAobGVuMSA9PSAwKQogICAgICAgIHJldHVybiAwOyAgIC8qIFR3byBudWxsIE9JRHMgYXJlICh0cml2aWFsbHkpIHRoZSBzYW1lICovCiAgICBpZiAoIW5hbWUxIHx8ICFuYW1lMikKICAgICAgICByZXR1cm4gMTsgICAvKiBPdGhlcndpc2Ugc29tZXRoaW5nJ3Mgd3JvbmcsIHNvIHJlcG9ydCBhIG5vbi1tYXRjaCAqLwogICAgLyoKICAgICAqIGZpbmQgZmlyc3Qgbm9uLW1hdGNoaW5nIE9JRCAKICAgICAqLwogICAgd2hpbGUgKGxlbi0tID4gMCkgewogICAgICAgIC8qCiAgICAgICAgICogdGhlc2UgbXVzdCBiZSBkb25lIGluIHNlcGVyYXRlIGNvbXBhcmlzb25zLCBzaW5jZQogICAgICAgICAqIHN1YnRyYWN0aW5nIHRoZW0gYW5kIHVzaW5nIHRoYXQgcmVzdWx0IGhhcyBwcm9ibGVtcyB3aXRoCiAgICAgICAgICogc3ViaWRzID4gMl4zMS4gCiAgICAgICAgICovCiAgICAgICAgaWYgKCoobmFtZTErKykgIT0gKihuYW1lMisrKSkKICAgICAgICAgICAgcmV0dXJuIDE7CiAgICB9CiAgICByZXR1cm4gMDsKfQoKLyoqIElkZW50aWNhbCB0byBuZXRzbm1wX29pZF9lcXVhbHMsIGV4Y2VwdCBvbmx5IHRoZSBsZW5ndGggdXAgdG8gbGVuMSBpcyBjb21wYXJlZC4KICogRnVuY3Rpb25hbGx5LCB0aGlzIGRldGVybWluZXMgaWYgaW5fbmFtZTIgaXMgZXF1YWwgb3IgYSBzdWJ0cmVlIG9mIGluX25hbWUxCiAqIEBwYXJhbSBpbl9uYW1lMSBBIHBvaW50ZXIgdG8gdGhlIGZpcnN0IG9pZC4KICogQHBhcmFtIGxlbjEgICAgIGxlbmd0aCBvZiB0aGUgZmlyc3QgT0lEIChpbiBzZWdtZW50cywgbm90IGJ5dGVzKQogKiBAcGFyYW0gaW5fbmFtZTIgQSBwb2ludGVyIHRvIHRoZSBzZWNvbmQgb2lkLgogKiBAcGFyYW0gbGVuMiAgICAgbGVuZ3RoIG9mIHRoZSBzZWNvbmQgT0lEIChpbiBzZWdtZW50cywgbm90IGJ5dGVzKQogKiBAcmV0dXJuIDAgaWYgb25lIGlzIGEgY29tbW9uIHByZWZpeCBvZiB0aGUgb3RoZXIuCiAqLyAKaW50Cm5ldHNubXBfb2lkX2lzX3N1YnRyZWUoY29uc3Qgb2lkICogaW5fbmFtZTEsCiAgICAgICAgICAgICAgICAgICAgICAgc2l6ZV90IGxlbjEsIGNvbnN0IG9pZCAqIGluX25hbWUyLCBzaXplX3QgbGVuMikKewogICAgaWYgKGxlbjEgPiBsZW4yKQogICAgICAgIHJldHVybiAxOwoKICAgIGlmIChtZW1jbXAoaW5fbmFtZTEsIGluX25hbWUyLCBsZW4xICogc2l6ZW9mKG9pZCkpKQogICAgICAgIHJldHVybiAxOwoKICAgIHJldHVybiAwOwp9CgovKiogR2l2ZW4gdHdvIE9JRHMsIGRldGVybWluZSB0aGUgY29tbW9uIHByZWZpeCB0byB0aGVtIGJvdGguCiAqIEBwYXJhbSBpbl9uYW1lMSBBIHBvaW50ZXIgdG8gdGhlIGZpcnN0IG9pZC4KICogQHBhcmFtIGxlbjEgICAgIExlbmd0aCBvZiB0aGUgZmlyc3Qgb2lkLgogKiBAcGFyYW0gaW5fbmFtZTIgQSBwb2ludGVyIHRvIHRoZSBzZWNvbmQgb2lkLgogKiBAcGFyYW0gbGVuMiAgICAgTGVuZ3RoIG9mIHRoZSBzZWNvbmQgb2lkLgogKiBAcmV0dXJuICAgICAgICAgbGVuZ3RoIG9mIGNvbW1vbiBwcmVmaXgKICogICAgICAgICAgICAgICAgIDAgaWYgbm8gY29tbW9uIHByZWZpeCwgLTEgb24gZXJyb3IuCiAqLwppbnQKbmV0c25tcF9vaWRfZmluZF9wcmVmaXgoY29uc3Qgb2lkICogaW5fbmFtZTEsIHNpemVfdCBsZW4xLAogICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBvaWQgKiBpbl9uYW1lMiwgc2l6ZV90IGxlbjIpCnsKICAgIGludCBpOwogICAgc2l6ZV90IG1pbl9zaXplOwoKICAgIGlmICghaW5fbmFtZTEgfHwgIWluX25hbWUyIHx8ICFsZW4xIHx8ICFsZW4yKQogICAgICAgIHJldHVybiAtMTsKCiAgICBpZiAoaW5fbmFtZTFbMF0gIT0gaW5fbmFtZTJbMF0pCiAgICAgICAgcmV0dXJuIDA7ICAgLyogTm8gbWF0Y2ggKi8KICAgIG1pbl9zaXplID0gU05NUF9NSU4obGVuMSwgbGVuMik7CiAgICBmb3IoaSA9IDA7IGkgPCAoaW50KW1pbl9zaXplOyBpKyspIHsKICAgICAgICBpZiAoaW5fbmFtZTFbaV0gIT0gaW5fbmFtZTJbaV0pCiAgICAgICAgICAgIHJldHVybiBpOyAgICAvKiAn7ScgaXMgdGhlIGZpcnN0IGRpZmZlcmluZyBzdWJpZGVudGlmaWVyCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBTbyB0aGUgY29tbW9uIHByZWZpeCBpcyAwLi4oaS0xKSwgb2YgbGVuZ3RoIGkgKi8KICAgIH0KICAgIHJldHVybiBtaW5fc2l6ZTsJLyogVGhlIHNob3J0ZXIgT0lEIGlzIGEgcHJlZml4IG9mIHRoZSBsb25nZXIsIGFuZAogICAgICAgICAgICAgICAgICAgICAgICAgICBoZW5jZSBpcyBwcmVjaXNlbHkgdGhlIGNvbW1vbiBwcmVmaXggb2YgdGhlIHR3by4KICAgICAgICAgICAgICAgICAgICAgICAgICAgUmV0dXJuIGl0cyBsZW5ndGguICovCn0KCnN0YXRpYyBpbnQgX2NoZWNrX3JhbmdlKHN0cnVjdCB0cmVlICp0cCwgbG9uZyBsdG1wLCBpbnQgKnJlc3B0ciwKCSAgICAgICAgICAgICAgICBjb25zdCBjaGFyICplcnJtc2cpCnsKICAgIGNoYXIgKmNwICAgPSBOVUxMOwogICAgY2hhciAqdGVtcCA9IE5VTEw7CiAgICBpbnQgICB0ZW1wX2xlbiA9IDA7CiAgICBpbnQgY2hlY2sgPSAhbmV0c25tcF9kc19nZXRfYm9vbGVhbihORVRTTk1QX0RTX0xJQlJBUllfSUQsCgkgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5FVFNOTVBfRFNfTElCX0RPTlRfQ0hFQ0tfUkFOR0UpOwogIAogICAgaWYgKGNoZWNrICYmIHRwICYmIHRwLT5yYW5nZXMpIHsKCXN0cnVjdCByYW5nZV9saXN0ICpycCA9IHRwLT5yYW5nZXM7Cgl3aGlsZSAocnApIHsKCSAgICBpZiAocnAtPmxvdyA8PSBsdG1wICYmIGx0bXAgPD0gcnAtPmhpZ2gpIGJyZWFrOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogQWxsb3cgZm91ciBkaWdpdHMgcGVyIHJhbmdlIHZhbHVlICovCiAgICAgICAgICAgIHRlbXBfbGVuICs9ICgocnAtPmxvdyAhPSBycC0+aGlnaCkgPyAxNCA6IDggKTsKCSAgICBycCA9IHJwLT5uZXh0OwoJfQoJaWYgKCFycCkgewoJICAgICpyZXNwdHIgPSBTTk1QRVJSX1JBTkdFOwogICAgICAgICAgICB0ZW1wID0gKGNoYXIgKiltYWxsb2MoIHRlbXBfbGVuK3N0cmxlbihlcnJtc2cpKzcpOwogICAgICAgICAgICBpZiAoIHRlbXAgKSB7CiAgICAgICAgICAgICAgICAvKiBBcHBlbmQgdGhlIERpc3BsYXkgSGludCByYW5nZSBpbmZvcm1hdGlvbiB0byB0aGUgZXJyb3IgbWVzc2FnZSAqLwogICAgICAgICAgICAgICAgc3ByaW50ZiggdGVtcCwgIiVzIDo6IHsiLCBlcnJtc2cgKTsKICAgICAgICAgICAgICAgIGNwID0gdGVtcCsoc3RybGVuKHRlbXApKTsKICAgICAgICAgICAgICAgIGZvciAoIHJwID0gdHAtPnJhbmdlczsgcnA7IHJwPXJwLT5uZXh0ICkgewogICAgICAgICAgICAgICAgICAgIGlmICggcnAtPmxvdyAhPSBycC0+aGlnaCApIAogICAgICAgICAgICAgICAgICAgICAgICBzcHJpbnRmKCBjcCwgIiglZC4uJWQpLCAiLCBycC0+bG93LCBycC0+aGlnaCApOwogICAgICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgICAgICAgICAgc3ByaW50ZiggY3AsICIoJWQpLCAiLCBycC0+bG93ICk7CiAgICAgICAgICAgICAgICAgICAgY3AgKz0gc3RybGVuKGNwKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICooY3AtMikgPSAnfSc7ICAgLyogUmVwbGFjZSB0aGUgZmluYWwgY29tbWEgd2l0aCBhICd9JyAqLwogICAgICAgICAgICAgICAgKihjcC0xKSA9IDA7CgkgICAgICAgIHNubXBfc2V0X2RldGFpbCh0ZW1wKTsKCSAgICAgICAgZnJlZSh0ZW1wKTsKICAgICAgICAgICAgfQoJICAgIHJldHVybiAwOwoJfQogICAgfQogICAgZnJlZSh0ZW1wKTsKICAgIHJldHVybiAxOwp9CiAgICAgICAgCgovKgogKiBBZGQgYSB2YXJpYWJsZSB3aXRoIHRoZSByZXF1ZXN0ZWQgbmFtZSB0byB0aGUgZW5kIG9mIHRoZSBsaXN0IG9mCiAqIHZhcmlhYmxlcyBmb3IgdGhpcyBwZHUuCiAqLwpuZXRzbm1wX3ZhcmlhYmxlX2xpc3QgKgpzbm1wX3BkdV9hZGRfdmFyaWFibGUobmV0c25tcF9wZHUgKnBkdSwKICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IG9pZCAqIG5hbWUsCiAgICAgICAgICAgICAgICAgICAgICBzaXplX3QgbmFtZV9sZW5ndGgsCiAgICAgICAgICAgICAgICAgICAgICB1X2NoYXIgdHlwZSwgY29uc3QgdV9jaGFyICogdmFsdWUsIHNpemVfdCBsZW4pCnsKICAgIHJldHVybiBzbm1wX3Zhcmxpc3RfYWRkX3ZhcmlhYmxlKCZwZHUtPnZhcmlhYmxlcywgbmFtZSwgbmFtZV9sZW5ndGgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0eXBlLCB2YWx1ZSwgbGVuKTsKfQoKLyoKICogQWRkIGEgdmFyaWFibGUgd2l0aCB0aGUgcmVxdWVzdGVkIG5hbWUgdG8gdGhlIGVuZCBvZiB0aGUgbGlzdCBvZgogKiB2YXJpYWJsZXMgZm9yIHRoaXMgcGR1LgogKi8KbmV0c25tcF92YXJpYWJsZV9saXN0ICoKc25tcF92YXJsaXN0X2FkZF92YXJpYWJsZShuZXRzbm1wX3ZhcmlhYmxlX2xpc3QgKiogdmFybGlzdCwKICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBvaWQgKiBuYW1lLAogICAgICAgICAgICAgICAgICAgICAgICAgIHNpemVfdCBuYW1lX2xlbmd0aCwKICAgICAgICAgICAgICAgICAgICAgICAgICB1X2NoYXIgdHlwZSwgY29uc3QgdV9jaGFyICogdmFsdWUsIHNpemVfdCBsZW4pCnsKICAgIG5ldHNubXBfdmFyaWFibGVfbGlzdCAqdmFycywgKnZ0bXA7CiAgICBpbnQgcmM7CgogICAgaWYgKHZhcmxpc3QgPT0gTlVMTCkKICAgICAgICByZXR1cm4gTlVMTDsKCiAgICB2YXJzID0gU05NUF9NQUxMT0NfVFlQRURFRihuZXRzbm1wX3ZhcmlhYmxlX2xpc3QpOwogICAgaWYgKHZhcnMgPT0gTlVMTCkKICAgICAgICByZXR1cm4gTlVMTDsKCiAgICB2YXJzLT50eXBlID0gdHlwZTsKCiAgICByYyA9IHNubXBfc2V0X3Zhcl92YWx1ZSggdmFycywgdmFsdWUsIGxlbiApOwogICAgaWYgKCggMCAhPSByYyApIHx8CiAgICAgICAgKG5hbWUgIT0gTlVMTCAmJiBzbm1wX3NldF92YXJfb2JqaWQodmFycywgbmFtZSwgbmFtZV9sZW5ndGgpKSkgewogICAgICAgIHNubXBfZnJlZV92YXIodmFycyk7CiAgICAgICAgcmV0dXJuICgwKTsKICAgIH0KCiAgICAvKgogICAgICogcHV0IG9ubHkgcXVhbGlmaWVkIHZhcmlhYmxlIG9udG8gdmFybGlzdCAKICAgICAqLwogICAgaWYgKCp2YXJsaXN0ID09IE5VTEwpIHsKICAgICAgICAqdmFybGlzdCA9IHZhcnM7CiAgICB9IGVsc2UgewogICAgICAgIGZvciAodnRtcCA9ICp2YXJsaXN0OyB2dG1wLT5uZXh0X3ZhcmlhYmxlOwogICAgICAgICAgICAgdnRtcCA9IHZ0bXAtPm5leHRfdmFyaWFibGUpOwoKICAgICAgICB2dG1wLT5uZXh0X3ZhcmlhYmxlID0gdmFyczsKICAgIH0KCiAgICByZXR1cm4gdmFyczsKfQoKCgovKgogKiBBZGQgYSB2YXJpYWJsZSB3aXRoIHRoZSByZXF1ZXN0ZWQgbmFtZSB0byB0aGUgZW5kIG9mIHRoZSBsaXN0IG9mCiAqIHZhcmlhYmxlcyBmb3IgdGhpcyBwZHUuCiAqIFJldHVybnM6CiAqIG1heSBzZXQgdGhlc2UgZXJyb3IgdHlwZXMgOgogKiBTTk1QRVJSX1JBTkdFIC0gdHlwZSwgdmFsdWUsIG9yIGxlbmd0aCBub3QgZm91bmQgb3Igb3V0IG9mIHJhbmdlCiAqIFNOTVBFUlJfVkFMVUUgLSB2YWx1ZSBpcyBub3QgY29ycmVjdAogKiBTTk1QRVJSX1ZBUl9UWVBFIC0gdHlwZSBpcyBub3QgY29ycmVjdAogKiBTTk1QRVJSX0JBRF9OQU1FIC0gbmFtZSBpcyBub3QgZm91bmQKICoKICogcmV0dXJucyAwIGlmIHN1Y2Nlc3MsIGVycm9yIGlmIGZhaWx1cmUuCiAqLwppbnQKc25tcF9hZGRfdmFyKG5ldHNubXBfcGR1ICpwZHUsCiAgICAgICAgICAgICBjb25zdCBvaWQgKiBuYW1lLCBzaXplX3QgbmFtZV9sZW5ndGgsIGNoYXIgdHlwZSwgY29uc3QgY2hhciAqdmFsdWUpCnsKICAgIGNoYXIgICAgICAgICAgICpzdDsKICAgIGNvbnN0IGNoYXIgICAgICpjcDsKICAgIGNoYXIgICAgICAgICAgICplY3AsICp2cDsKICAgIGludCAgICAgICAgICAgICByZXN1bHQgPSBTTk1QRVJSX1NVQ0NFU1M7CiNpZm5kZWYgTkVUU05NUF9ESVNBQkxFX01JQl9MT0FESU5HCiAgICBpbnQgICAgICAgICAgICAgY2hlY2sgPSAhbmV0c25tcF9kc19nZXRfYm9vbGVhbihORVRTTk1QX0RTX0xJQlJBUllfSUQsCgkJCQkJICAgICBORVRTTk1QX0RTX0xJQl9ET05UX0NIRUNLX1JBTkdFKTsKICAgIGludCAgICAgICAgICAgICBkb19oaW50ID0gIW5ldHNubXBfZHNfZ2V0X2Jvb2xlYW4oTkVUU05NUF9EU19MSUJSQVJZX0lELAoJCQkJCSAgICAgTkVUU05NUF9EU19MSUJfTk9fRElTUExBWV9ISU5UKTsKICAgIHVfY2hhciAgICAgICAgICpoaW50cHRyOwogICAgc3RydWN0IHRyZWUgICAgKnRwOwojZW5kaWYgLyogTkVUU05NUF9ESVNBQkxFX01JQl9MT0FESU5HICovCiAgICB1X2NoYXIgICAgICAgICAqYnVmID0gTlVMTDsKICAgIGNvbnN0IHVfY2hhciAgICpidWZfcHRyID0gTlVMTDsKICAgIHNpemVfdCAgICAgICAgICBidWZfbGVuID0gMCwgdmFsdWVfbGVuID0gMCwgdGludDsKICAgIGluX2FkZHJfdCAgICAgICBhdG1wOwogICAgbG9uZyAgICAgICAgICAgIGx0bXA7CiAgICBpbnQgICAgICAgICAgICAgaXRtcDsKICAgIHN0cnVjdCBlbnVtX2xpc3QgKmVwOwojaWZkZWYgTkVUU05NUF9XSVRIX09QQVFVRV9TUEVDSUFMX1RZUEVTCiAgICBkb3VibGUgICAgICAgICAgZHRtcDsKICAgIGZsb2F0ICAgICAgICAgICBmdG1wOwojZW5kaWYgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIE5FVFNOTVBfV0lUSF9PUEFRVUVfU1BFQ0lBTF9UWVBFUyAqLwogICAgc3RydWN0IGNvdW50ZXI2NCBjNjR0bXA7CgojaWZuZGVmIE5FVFNOTVBfRElTQUJMRV9NSUJfTE9BRElORwogICAgdHAgPSBnZXRfdHJlZShuYW1lLCBuYW1lX2xlbmd0aCwgZ2V0X3RyZWVfaGVhZCgpKTsKICAgIGlmICghdHAgfHwgIXRwLT50eXBlIHx8IHRwLT50eXBlID4gVFlQRV9TSU1QTEVfTEFTVCkgewogICAgICAgIGNoZWNrID0gMDsKICAgIH0KICAgIGlmICghKHRwICYmIHRwLT5oaW50KSkKCWRvX2hpbnQgPSAwOwoKICAgIGlmICh0cCAmJiB0eXBlID09ICc9JykgewogICAgICAgIC8qCiAgICAgICAgICogZ2VuZXJpYyBhc3NpZ25tZW50IC0gbGV0IHRoZSB0cmVlIG5vZGUgZGVjaWRlIHZhbHVlIGZvcm1hdCAKICAgICAgICAgKi8KICAgICAgICBzd2l0Y2ggKHRwLT50eXBlKSB7CiAgICAgICAgY2FzZSBUWVBFX0lOVEVHRVI6CiAgICAgICAgY2FzZSBUWVBFX0lOVEVHRVIzMjoKICAgICAgICAgICAgdHlwZSA9ICdpJzsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSBUWVBFX0dBVUdFOgogICAgICAgIGNhc2UgVFlQRV9VTlNJR05FRDMyOgogICAgICAgICAgICB0eXBlID0gJ3UnOwogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIFRZUEVfVUlOVEVHRVI6CiAgICAgICAgICAgIHR5cGUgPSAnMyc7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgVFlQRV9DT1VOVEVSOgogICAgICAgICAgICB0eXBlID0gJ2MnOwogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIFRZUEVfQ09VTlRFUjY0OgogICAgICAgICAgICB0eXBlID0gJ0MnOwogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIFRZUEVfVElNRVRJQ0tTOgogICAgICAgICAgICB0eXBlID0gJ3QnOwogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIFRZUEVfT0NURVRTVFI6CiAgICAgICAgICAgIHR5cGUgPSAncyc7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgVFlQRV9CSVRTVFJJTkc6CiAgICAgICAgICAgIHR5cGUgPSAnYic7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgVFlQRV9JUEFERFI6CiAgICAgICAgICAgIHR5cGUgPSAnYSc7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgVFlQRV9PQkpJRDoKICAgICAgICAgICAgdHlwZSA9ICdvJzsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgfQogICAgfQojZW5kaWYgLyogTkVUU05NUF9ESVNBQkxFX01JQl9MT0FESU5HICovCgogICAgc3dpdGNoICh0eXBlKSB7CiAgICBjYXNlICdpJzoKI2lmbmRlZiBORVRTTk1QX0RJU0FCTEVfTUlCX0xPQURJTkcKICAgICAgICBpZiAoY2hlY2sgJiYgdHAtPnR5cGUgIT0gVFlQRV9JTlRFR0VSCiAgICAgICAgICAgICYmIHRwLT50eXBlICE9IFRZUEVfSU5URUdFUjMyKSB7CiAgICAgICAgICAgIHZhbHVlID0gIklOVEVHRVIiOwogICAgICAgICAgICByZXN1bHQgPSBTTk1QRVJSX1ZBTFVFOwogICAgICAgICAgICBnb3RvIHR5cGVfZXJyb3I7CiAgICAgICAgfQojZW5kaWYgLyogTkVUU05NUF9ESVNBQkxFX01JQl9MT0FESU5HICovCiAgICAgICAgaWYgKCEqdmFsdWUpCiAgICAgICAgICAgIGdvdG8gZmFpbDsKICAgICAgICBsdG1wID0gc3RydG9sKHZhbHVlLCAmZWNwLCAxMCk7CiAgICAgICAgaWYgKCplY3ApIHsKI2lmbmRlZiBORVRTTk1QX0RJU0FCTEVfTUlCX0xPQURJTkcKICAgICAgICAgICAgZXAgPSB0cCA/IHRwLT5lbnVtcyA6IE5VTEw7CiAgICAgICAgICAgIHdoaWxlIChlcCkgewogICAgICAgICAgICAgICAgaWYgKHN0cmNtcCh2YWx1ZSwgZXAtPmxhYmVsKSA9PSAwKSB7CiAgICAgICAgICAgICAgICAgICAgbHRtcCA9IGVwLT52YWx1ZTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGVwID0gZXAtPm5leHQ7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKCFlcCkgewojZW5kaWYgLyogTkVUU05NUF9ESVNBQkxFX01JQl9MT0FESU5HICovCiAgICAgICAgICAgICAgICByZXN1bHQgPSBTTk1QRVJSX1JBTkdFOyAgIC8qID8/IG9yIFNOTVBFUlJfVkFMVUU7ICovCiAgICAgICAgICAgICAgICBzbm1wX3NldF9kZXRhaWwodmFsdWUpOwogICAgICAgICAgICAgICAgYnJlYWs7CiNpZm5kZWYgTkVUU05NUF9ESVNBQkxFX01JQl9MT0FESU5HCiAgICAgICAgICAgIH0KI2VuZGlmIC8qIE5FVFNOTVBfRElTQUJMRV9NSUJfTE9BRElORyAqLwogICAgICAgIH0KCiNpZm5kZWYgTkVUU05NUF9ESVNBQkxFX01JQl9MT0FESU5HCiAgICAgICAgaWYgKCFfY2hlY2tfcmFuZ2UodHAsIGx0bXAsICZyZXN1bHQsIHZhbHVlKSkKICAgICAgICAgICAgYnJlYWs7CiNlbmRpZiAvKiBORVRTTk1QX0RJU0FCTEVfTUlCX0xPQURJTkcgKi8KICAgICAgICBzbm1wX3BkdV9hZGRfdmFyaWFibGUocGR1LCBuYW1lLCBuYW1lX2xlbmd0aCwgQVNOX0lOVEVHRVIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICh1X2NoYXIgKikgJiBsdG1wLCBzaXplb2YobHRtcCkpOwogICAgICAgIGJyZWFrOwoKICAgIGNhc2UgJ3UnOgojaWZuZGVmIE5FVFNOTVBfRElTQUJMRV9NSUJfTE9BRElORwogICAgICAgIGlmIChjaGVjayAmJiB0cC0+dHlwZSAhPSBUWVBFX0dBVUdFICYmIHRwLT50eXBlICE9IFRZUEVfVU5TSUdORUQzMikgewogICAgICAgICAgICB2YWx1ZSA9ICJVbnNpZ25lZDMyIjsKICAgICAgICAgICAgcmVzdWx0ID0gU05NUEVSUl9WQUxVRTsKICAgICAgICAgICAgZ290byB0eXBlX2Vycm9yOwogICAgICAgIH0KI2VuZGlmIC8qIE5FVFNOTVBfRElTQUJMRV9NSUJfTE9BRElORyAqLwogICAgICAgIGx0bXAgPSBzdHJ0b3VsKHZhbHVlLCAmZWNwLCAxMCk7CiAgICAgICAgaWYgKCp2YWx1ZSAmJiAhKmVjcCkKICAgICAgICAgICAgc25tcF9wZHVfYWRkX3ZhcmlhYmxlKHBkdSwgbmFtZSwgbmFtZV9sZW5ndGgsIEFTTl9VTlNJR05FRCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICh1X2NoYXIgKikgJiBsdG1wLCBzaXplb2YobHRtcCkpOwogICAgICAgIGVsc2UKICAgICAgICAgICAgZ290byBmYWlsOwogICAgICAgIGJyZWFrOwoKICAgIGNhc2UgJzMnOgojaWZuZGVmIE5FVFNOTVBfRElTQUJMRV9NSUJfTE9BRElORwogICAgICAgIGlmIChjaGVjayAmJiB0cC0+dHlwZSAhPSBUWVBFX1VJTlRFR0VSKSB7CiAgICAgICAgICAgIHZhbHVlID0gIlVJbnRlZ2VyMzIiOwogICAgICAgICAgICByZXN1bHQgPSBTTk1QRVJSX1ZBTFVFOwogICAgICAgICAgICBnb3RvIHR5cGVfZXJyb3I7CiAgICAgICAgfQojZW5kaWYgLyogTkVUU05NUF9ESVNBQkxFX01JQl9MT0FESU5HICovCiAgICAgICAgbHRtcCA9IHN0cnRvdWwodmFsdWUsICZlY3AsIDEwKTsKICAgICAgICBpZiAoKnZhbHVlICYmICEqZWNwKQogICAgICAgICAgICBzbm1wX3BkdV9hZGRfdmFyaWFibGUocGR1LCBuYW1lLCBuYW1lX2xlbmd0aCwgQVNOX1VJTlRFR0VSLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKHVfY2hhciAqKSAmIGx0bXAsIHNpemVvZihsdG1wKSk7CiAgICAgICAgZWxzZQogICAgICAgICAgICBnb3RvIGZhaWw7CiAgICAgICAgYnJlYWs7CgogICAgY2FzZSAnYyc6CiNpZm5kZWYgTkVUU05NUF9ESVNBQkxFX01JQl9MT0FESU5HCiAgICAgICAgaWYgKGNoZWNrICYmIHRwLT50eXBlICE9IFRZUEVfQ09VTlRFUikgewogICAgICAgICAgICB2YWx1ZSA9ICJDb3VudGVyMzIiOwogICAgICAgICAgICByZXN1bHQgPSBTTk1QRVJSX1ZBTFVFOwogICAgICAgICAgICBnb3RvIHR5cGVfZXJyb3I7CiAgICAgICAgfQojZW5kaWYgLyogTkVUU05NUF9ESVNBQkxFX01JQl9MT0FESU5HICovCiAgICAgICAgbHRtcCA9IHN0cnRvdWwodmFsdWUsICZlY3AsIDEwKTsKICAgICAgICBpZiAoKnZhbHVlICYmICEqZWNwKQogICAgICAgICAgICBzbm1wX3BkdV9hZGRfdmFyaWFibGUocGR1LCBuYW1lLCBuYW1lX2xlbmd0aCwgQVNOX0NPVU5URVIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAodV9jaGFyICopICYgbHRtcCwgc2l6ZW9mKGx0bXApKTsKICAgICAgICBlbHNlCiAgICAgICAgICAgIGdvdG8gZmFpbDsKICAgICAgICBicmVhazsKCiAgICBjYXNlICdDJzoKI2lmbmRlZiBORVRTTk1QX0RJU0FCTEVfTUlCX0xPQURJTkcKICAgICAgICBpZiAoY2hlY2sgJiYgdHAtPnR5cGUgIT0gVFlQRV9DT1VOVEVSNjQpIHsKICAgICAgICAgICAgdmFsdWUgPSAiQ291bnRlcjY0IjsKICAgICAgICAgICAgcmVzdWx0ID0gU05NUEVSUl9WQUxVRTsKICAgICAgICAgICAgZ290byB0eXBlX2Vycm9yOwogICAgICAgIH0KI2VuZGlmIC8qIE5FVFNOTVBfRElTQUJMRV9NSUJfTE9BRElORyAqLwogICAgICAgIGlmIChyZWFkNjQoJmM2NHRtcCwgdmFsdWUpKQogICAgICAgICAgICBzbm1wX3BkdV9hZGRfdmFyaWFibGUocGR1LCBuYW1lLCBuYW1lX2xlbmd0aCwgQVNOX0NPVU5URVI2NCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICh1X2NoYXIgKikgJiBjNjR0bXAsIHNpemVvZihjNjR0bXApKTsKICAgICAgICBlbHNlCiAgICAgICAgICAgIGdvdG8gZmFpbDsKICAgICAgICBicmVhazsKCiAgICBjYXNlICd0JzoKI2lmbmRlZiBORVRTTk1QX0RJU0FCTEVfTUlCX0xPQURJTkcKICAgICAgICBpZiAoY2hlY2sgJiYgdHAtPnR5cGUgIT0gVFlQRV9USU1FVElDS1MpIHsKICAgICAgICAgICAgdmFsdWUgPSAiVGltZXRpY2tzIjsKICAgICAgICAgICAgcmVzdWx0ID0gU05NUEVSUl9WQUxVRTsKICAgICAgICAgICAgZ290byB0eXBlX2Vycm9yOwogICAgICAgIH0KI2VuZGlmIC8qIE5FVFNOTVBfRElTQUJMRV9NSUJfTE9BRElORyAqLwogICAgICAgIGx0bXAgPSBzdHJ0b3VsKHZhbHVlLCAmZWNwLCAxMCk7CiAgICAgICAgaWYgKCp2YWx1ZSAmJiAhKmVjcCkKICAgICAgICAgICAgc25tcF9wZHVfYWRkX3ZhcmlhYmxlKHBkdSwgbmFtZSwgbmFtZV9sZW5ndGgsIEFTTl9USU1FVElDS1MsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAodV9jaGFyICopICYgbHRtcCwgc2l6ZW9mKGxvbmcpKTsKICAgICAgICBlbHNlCiAgICAgICAgICAgIGdvdG8gZmFpbDsKICAgICAgICBicmVhazsKCiAgICBjYXNlICdhJzoKI2lmbmRlZiBORVRTTk1QX0RJU0FCTEVfTUlCX0xPQURJTkcKICAgICAgICBpZiAoY2hlY2sgJiYgdHAtPnR5cGUgIT0gVFlQRV9JUEFERFIpIHsKICAgICAgICAgICAgdmFsdWUgPSAiSXBBZGRyZXNzIjsKICAgICAgICAgICAgcmVzdWx0ID0gU05NUEVSUl9WQUxVRTsKICAgICAgICAgICAgZ290byB0eXBlX2Vycm9yOwogICAgICAgIH0KI2VuZGlmIC8qIE5FVFNOTVBfRElTQUJMRV9NSUJfTE9BRElORyAqLwogICAgICAgIGF0bXAgPSBpbmV0X2FkZHIodmFsdWUpOwogICAgICAgIGlmIChhdG1wICE9IChpbl9hZGRyX3QpIC0xIHx8ICFzdHJjbXAodmFsdWUsICIyNTUuMjU1LjI1NS4yNTUiKSkKICAgICAgICAgICAgc25tcF9wZHVfYWRkX3ZhcmlhYmxlKHBkdSwgbmFtZSwgbmFtZV9sZW5ndGgsIEFTTl9JUEFERFJFU1MsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAodV9jaGFyICopICYgYXRtcCwgc2l6ZW9mKGF0bXApKTsKICAgICAgICBlbHNlCiAgICAgICAgICAgIGdvdG8gZmFpbDsKICAgICAgICBicmVhazsKCiAgICBjYXNlICdvJzoKI2lmbmRlZiBORVRTTk1QX0RJU0FCTEVfTUlCX0xPQURJTkcKICAgICAgICBpZiAoY2hlY2sgJiYgdHAtPnR5cGUgIT0gVFlQRV9PQkpJRCkgewogICAgICAgICAgICB2YWx1ZSA9ICJPQkpFQ1QgSURFTlRJRklFUiI7CiAgICAgICAgICAgIHJlc3VsdCA9IFNOTVBFUlJfVkFMVUU7CiAgICAgICAgICAgIGdvdG8gdHlwZV9lcnJvcjsKICAgICAgICB9CiNlbmRpZiAvKiBORVRTTk1QX0RJU0FCTEVfTUlCX0xPQURJTkcgKi8KICAgICAgICBpZiAoKGJ1ZiA9ICh1X2NoYXIgKiltYWxsb2Moc2l6ZW9mKG9pZCkgKiBNQVhfT0lEX0xFTikpID09IE5VTEwpIHsKICAgICAgICAgICAgcmVzdWx0ID0gU05NUEVSUl9NQUxMT0M7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgdGludCA9IE1BWF9PSURfTEVOOwogICAgICAgICAgICBpZiAoc25tcF9wYXJzZV9vaWQodmFsdWUsIChvaWQgKikgYnVmLCAmdGludCkpIHsKICAgICAgICAgICAgICAgIHNubXBfcGR1X2FkZF92YXJpYWJsZShwZHUsIG5hbWUsIG5hbWVfbGVuZ3RoLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEFTTl9PQkpFQ1RfSUQsIGJ1ZiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaXplb2Yob2lkKSAqIHRpbnQpOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgcmVzdWx0ID0gc25tcF9lcnJubzsgICAgLypNVENSSVRJQ0FMX1JFU09VUkNFICovCiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgYnJlYWs7CgogICAgY2FzZSAncyc6CiAgICBjYXNlICd4JzoKICAgIGNhc2UgJ2QnOgojaWZuZGVmIE5FVFNOTVBfRElTQUJMRV9NSUJfTE9BRElORwogICAgICAgIGlmIChjaGVjayAmJiB0cC0+dHlwZSAhPSBUWVBFX09DVEVUU1RSICYmIHRwLT50eXBlICE9IFRZUEVfQklUU1RSSU5HKSB7CiAgICAgICAgICAgIHZhbHVlID0gIk9DVEVUIFNUUklORyI7CiAgICAgICAgICAgIHJlc3VsdCA9IFNOTVBFUlJfVkFMVUU7CiAgICAgICAgICAgIGdvdG8gdHlwZV9lcnJvcjsKICAgICAgICB9CglpZiAoJ3MnID09IHR5cGUgJiYgZG9faGludCAmJiAhcGFyc2Vfb2N0ZXRfaGludCh0cC0+aGludCwgdmFsdWUsICZoaW50cHRyLCAmaXRtcCkpIHsKICAgICAgICAgICAgaWYgKF9jaGVja19yYW5nZSh0cCwgaXRtcCwgJnJlc3VsdCwgIlZhbHVlIGRvZXMgbm90IG1hdGNoIERJU1BMQVktSElOVCIpKSB7CiAgICAgICAgICAgICAgICBzbm1wX3BkdV9hZGRfdmFyaWFibGUocGR1LCBuYW1lLCBuYW1lX2xlbmd0aCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBU05fT0NURVRfU1RSLCBoaW50cHRyLCBpdG1wKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBTTk1QX0ZSRUUoaGludHB0cik7CiAgICAgICAgICAgIGhpbnRwdHIgPSBidWY7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIH0KI2VuZGlmIC8qIE5FVFNOTVBfRElTQUJMRV9NSUJfTE9BRElORyAqLwogICAgICAgIGlmICh0eXBlID09ICdkJykgewogICAgICAgICAgICBpZiAoIXNubXBfZGVjaW1hbF90b19iaW5hcnkKICAgICAgICAgICAgICAgICgmYnVmLCAmYnVmX2xlbiwgJnZhbHVlX2xlbiwgMSwgdmFsdWUpKSB7CiAgICAgICAgICAgICAgICByZXN1bHQgPSBTTk1QRVJSX1ZBTFVFOwogICAgICAgICAgICAgICAgc25tcF9zZXRfZGV0YWlsKHZhbHVlKTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGJ1Zl9wdHIgPSBidWY7CiAgICAgICAgfSBlbHNlIGlmICh0eXBlID09ICd4JykgewogICAgICAgICAgICBpZiAoIXNubXBfaGV4X3RvX2JpbmFyeSgmYnVmLCAmYnVmX2xlbiwgJnZhbHVlX2xlbiwgMSwgdmFsdWUpKSB7CiAgICAgICAgICAgICAgICByZXN1bHQgPSBTTk1QRVJSX1ZBTFVFOwogICAgICAgICAgICAgICAgc25tcF9zZXRfZGV0YWlsKHZhbHVlKTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9CiAgICAgICAgICAgIC8qIGluaXRpYWxpemUgaXRtcCB2YWx1ZSBzbyB0aGF0IHJhbmdlIGNoZWNrIGJlbG93IHdvcmtzICovCiAgICAgICAgICAgIGl0bXAgPSB2YWx1ZV9sZW47CiAgICAgICAgICAgIGJ1Zl9wdHIgPSBidWY7CiAgICAgICAgfSBlbHNlIGlmICh0eXBlID09ICdzJykgewogICAgICAgICAgICBidWZfcHRyID0gKGNvbnN0IHVfY2hhciAqKXZhbHVlOwogICAgICAgICAgICB2YWx1ZV9sZW4gPSBzdHJsZW4odmFsdWUpOwogICAgICAgIH0KI2lmbmRlZiBORVRTTk1QX0RJU0FCTEVfTUlCX0xPQURJTkcKICAgICAgICBpZiAoIV9jaGVja19yYW5nZSh0cCwgdmFsdWVfbGVuLCAmcmVzdWx0LCAiQmFkIHN0cmluZyBsZW5ndGgiKSkKICAgICAgICAgICAgYnJlYWs7CiNlbmRpZiAvKiBORVRTTk1QX0RJU0FCTEVfTUlCX0xPQURJTkcgKi8KICAgICAgICBzbm1wX3BkdV9hZGRfdmFyaWFibGUocGR1LCBuYW1lLCBuYW1lX2xlbmd0aCwgQVNOX09DVEVUX1NUUiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnVmX3B0ciwgdmFsdWVfbGVuKTsKICAgICAgICBicmVhazsKCiAgICBjYXNlICduJzoKICAgICAgICBzbm1wX3BkdV9hZGRfdmFyaWFibGUocGR1LCBuYW1lLCBuYW1lX2xlbmd0aCwgQVNOX05VTEwsIDAsIDApOwogICAgICAgIGJyZWFrOwoKICAgIGNhc2UgJ2InOgojaWZuZGVmIE5FVFNOTVBfRElTQUJMRV9NSUJfTE9BRElORwogICAgICAgIGlmIChjaGVjayAmJiAodHAtPnR5cGUgIT0gVFlQRV9CSVRTVFJJTkcgfHwgIXRwLT5lbnVtcykpIHsKICAgICAgICAgICAgdmFsdWUgPSAiQklUUyI7CiAgICAgICAgICAgIHJlc3VsdCA9IFNOTVBFUlJfVkFMVUU7CiAgICAgICAgICAgIGdvdG8gdHlwZV9lcnJvcjsKICAgICAgICB9CiNlbmRpZiAvKiBORVRTTk1QX0RJU0FCTEVfTUlCX0xPQURJTkcgKi8KICAgICAgICB0aW50ID0gMDsKICAgICAgICBpZiAoKGJ1ZiA9ICh1X2NoYXIgKikgbWFsbG9jKDI1NikpID09IE5VTEwpIHsKICAgICAgICAgICAgcmVzdWx0ID0gU05NUEVSUl9NQUxMT0M7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGJ1Zl9sZW4gPSAyNTY7CiAgICAgICAgICAgIG1lbXNldChidWYsIDAsIGJ1Zl9sZW4pOwogICAgICAgIH0KCiNpZm5kZWYgTkVUU05NUF9ESVNBQkxFX01JQl9MT0FESU5HCiAgICAgICAgZm9yIChlcCA9IHRwID8gdHAtPmVudW1zIDogTlVMTDsgZXA7IGVwID0gZXAtPm5leHQpIHsKICAgICAgICAgICAgaWYgKGVwLT52YWx1ZSAvIDggPj0gKGludCkgdGludCkgewogICAgICAgICAgICAgICAgdGludCA9IGVwLT52YWx1ZSAvIDggKyAxOwogICAgICAgICAgICB9CiAgICAgICAgfQojZW5kaWYgLyogTkVUU05NUF9ESVNBQkxFX01JQl9MT0FESU5HICovCgoJdnAgPSBzdHJkdXAodmFsdWUpOwoJZm9yIChjcCA9IHN0cnRva19yKHZwLCAiICxcdCIsICZzdCk7IGNwOyBjcCA9IHN0cnRva19yKE5VTEwsICIgLFx0IiwgJnN0KSkgewogICAgICAgICAgICBpbnQgICAgICAgICAgICAgaXgsIGJpdDsKCiAgICAgICAgICAgIGx0bXAgPSBzdHJ0b3VsKGNwLCAmZWNwLCAwKTsKICAgICAgICAgICAgaWYgKCplY3AgIT0gMCkgewojaWZuZGVmIE5FVFNOTVBfRElTQUJMRV9NSUJfTE9BRElORwogICAgICAgICAgICAgICAgZm9yIChlcCA9IHRwID8gdHAtPmVudW1zIDogTlVMTDsgZXAgIT0gTlVMTDsgZXAgPSBlcC0+bmV4dCkgewogICAgICAgICAgICAgICAgICAgIGlmIChzdHJuY21wKGVwLT5sYWJlbCwgY3AsIHN0cmxlbihlcC0+bGFiZWwpKSA9PSAwKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlmIChlcCAhPSBOVUxMKSB7CiAgICAgICAgICAgICAgICAgICAgbHRtcCA9IGVwLT52YWx1ZTsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiNlbmRpZiAvKiBORVRTTk1QX0RJU0FCTEVfTUlCX0xPQURJTkcgKi8KICAgICAgICAgICAgICAgICAgICByZXN1bHQgPSBTTk1QRVJSX1JBTkdFOyAgIC8qID8/IG9yIFNOTVBFUlJfVkFMVUU7ICovCiAgICAgICAgICAgICAgICAgICAgc25tcF9zZXRfZGV0YWlsKGNwKTsKICAgICAgICAgICAgICAgICAgICBTTk1QX0ZSRUUoYnVmKTsKCQkgICAgU05NUF9GUkVFKHZwKTsKICAgICAgICAgICAgICAgICAgICBnb3RvIG91dDsKI2lmbmRlZiBORVRTTk1QX0RJU0FCTEVfTUlCX0xPQURJTkcKICAgICAgICAgICAgICAgIH0KI2VuZGlmIC8qIE5FVFNOTVBfRElTQUJMRV9NSUJfTE9BRElORyAqLwogICAgICAgICAgICB9CgogICAgICAgICAgICBpeCA9IGx0bXAgLyA4OwogICAgICAgICAgICBpZiAoaXggPj0gKGludCkgdGludCkgewogICAgICAgICAgICAgICAgdGludCA9IGl4ICsgMTsKICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAoaXggPj0gKGludClidWZfbGVuICYmICFzbm1wX3JlYWxsb2MoJmJ1ZiwgJmJ1Zl9sZW4pKSB7CiAgICAgICAgICAgICAgICByZXN1bHQgPSBTTk1QRVJSX01BTExPQzsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGJpdCA9IDB4ODAgPj4gbHRtcCAlIDg7CiAgICAgICAgICAgIGJ1ZltpeF0gfD0gYml0OwoJICAgIAogICAgICAgIH0KCVNOTVBfRlJFRSh2cCk7CiAgICAgICAgc25tcF9wZHVfYWRkX3ZhcmlhYmxlKHBkdSwgbmFtZSwgbmFtZV9sZW5ndGgsIEFTTl9PQ1RFVF9TVFIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJ1ZiwgdGludCk7CiAgICAgICAgYnJlYWs7CgojaWZkZWYgTkVUU05NUF9XSVRIX09QQVFVRV9TUEVDSUFMX1RZUEVTCiAgICBjYXNlICdVJzoKICAgICAgICBpZiAocmVhZDY0KCZjNjR0bXAsIHZhbHVlKSkKICAgICAgICAgICAgc25tcF9wZHVfYWRkX3ZhcmlhYmxlKHBkdSwgbmFtZSwgbmFtZV9sZW5ndGgsIEFTTl9PUEFRVUVfVTY0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKHVfY2hhciAqKSAmIGM2NHRtcCwgc2l6ZW9mKGM2NHRtcCkpOwogICAgICAgIGVsc2UKICAgICAgICAgICAgZ290byBmYWlsOwogICAgICAgIGJyZWFrOwoKICAgIGNhc2UgJ0knOgogICAgICAgIGlmIChyZWFkNjQoJmM2NHRtcCwgdmFsdWUpKQogICAgICAgICAgICBzbm1wX3BkdV9hZGRfdmFyaWFibGUocGR1LCBuYW1lLCBuYW1lX2xlbmd0aCwgQVNOX09QQVFVRV9JNjQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAodV9jaGFyICopICYgYzY0dG1wLCBzaXplb2YoYzY0dG1wKSk7CiAgICAgICAgZWxzZQogICAgICAgICAgICBnb3RvIGZhaWw7CiAgICAgICAgYnJlYWs7CgogICAgY2FzZSAnRic6CiAgICAgICAgaWYgKHNzY2FuZih2YWx1ZSwgIiVmIiwgJmZ0bXApID09IDEpCiAgICAgICAgICAgIHNubXBfcGR1X2FkZF92YXJpYWJsZShwZHUsIG5hbWUsIG5hbWVfbGVuZ3RoLCBBU05fT1BBUVVFX0ZMT0FULAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKHVfY2hhciAqKSAmIGZ0bXAsIHNpemVvZihmdG1wKSk7CiAgICAgICAgZWxzZQogICAgICAgICAgICBnb3RvIGZhaWw7CiAgICAgICAgYnJlYWs7CgogICAgY2FzZSAnRCc6CiAgICAgICAgaWYgKHNzY2FuZih2YWx1ZSwgIiVsZiIsICZkdG1wKSA9PSAxKQogICAgICAgICAgICBzbm1wX3BkdV9hZGRfdmFyaWFibGUocGR1LCBuYW1lLCBuYW1lX2xlbmd0aCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEFTTl9PUEFRVUVfRE9VQkxFLCAodV9jaGFyICopICYgZHRtcCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNpemVvZihkdG1wKSk7CiAgICAgICAgZWxzZQogICAgICAgICAgICBnb3RvIGZhaWw7CiAgICAgICAgYnJlYWs7CiNlbmRpZiAgICAgICAgICAgICAgICAgICAgICAgICAgLyogTkVUU05NUF9XSVRIX09QQVFVRV9TUEVDSUFMX1RZUEVTICovCgogICAgZGVmYXVsdDoKICAgICAgICByZXN1bHQgPSBTTk1QRVJSX1ZBUl9UWVBFOwoJYnVmID0gKHVfY2hhciAqKWNhbGxvYygxLCA0KTsKCWlmIChidWYgIT0gTlVMTCkgewoJICAgIHNwcmludGYoKGNoYXIgKilidWYsICJcIiVjXCIiLCB0eXBlKTsKCSAgICBzbm1wX3NldF9kZXRhaWwoKGNoYXIgKilidWYpOwoJfQogICAgICAgIGJyZWFrOwogICAgfQoKICAgIFNOTVBfRlJFRShidWYpOwogICAgU0VUX1NOTVBfRVJST1IocmVzdWx0KTsKICAgIHJldHVybiByZXN1bHQ7CgojaWZuZGVmIE5FVFNOTVBfRElTQUJMRV9NSUJfTE9BRElORwogIHR5cGVfZXJyb3I6CiAgICB7CiAgICAgICAgY2hhciAgICAgICAgICAgIGVycm9yX21zZ1syNTZdOwogICAgICAgIGNoYXIgICAgICAgICAgICB1bmRlZl9tc2dbMzJdOwogICAgICAgIGNvbnN0IGNoYXIgICAgICp2YXJfdHlwZTsKICAgICAgICBzd2l0Y2ggKHRwLT50eXBlKSB7CiAgICAgICAgY2FzZSBUWVBFX09CSklEOgogICAgICAgICAgICB2YXJfdHlwZSA9ICJPQkpFQ1QgSURFTlRJRklFUiI7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgVFlQRV9PQ1RFVFNUUjoKICAgICAgICAgICAgdmFyX3R5cGUgPSAiT0NURVQgU1RSSU5HIjsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSBUWVBFX0lOVEVHRVI6CiAgICAgICAgICAgIHZhcl90eXBlID0gIklOVEVHRVIiOwogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIFRZUEVfTkVUQUREUjoKICAgICAgICAgICAgdmFyX3R5cGUgPSAiTmV0d29ya0FkZHJlc3MiOwogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIFRZUEVfSVBBRERSOgogICAgICAgICAgICB2YXJfdHlwZSA9ICJJcEFkZHJlc3MiOwogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIFRZUEVfQ09VTlRFUjoKICAgICAgICAgICAgdmFyX3R5cGUgPSAiQ291bnRlcjMyIjsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSBUWVBFX0dBVUdFOgogICAgICAgICAgICB2YXJfdHlwZSA9ICJHYXVnZTMyIjsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSBUWVBFX1RJTUVUSUNLUzoKICAgICAgICAgICAgdmFyX3R5cGUgPSAiVGltZXRpY2tzIjsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSBUWVBFX09QQVFVRToKICAgICAgICAgICAgdmFyX3R5cGUgPSAiT3BhcXVlIjsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSBUWVBFX05VTEw6CiAgICAgICAgICAgIHZhcl90eXBlID0gIk51bGwiOwogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIFRZUEVfQ09VTlRFUjY0OgogICAgICAgICAgICB2YXJfdHlwZSA9ICJDb3VudGVyNjQiOwogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIFRZUEVfQklUU1RSSU5HOgogICAgICAgICAgICB2YXJfdHlwZSA9ICJCSVRTIjsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSBUWVBFX05TQVBBRERSRVNTOgogICAgICAgICAgICB2YXJfdHlwZSA9ICJOc2FwQWRkcmVzcyI7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgVFlQRV9VSU5URUdFUjoKICAgICAgICAgICAgdmFyX3R5cGUgPSAiVUludGVnZXIiOwogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIFRZUEVfVU5TSUdORUQzMjoKICAgICAgICAgICAgdmFyX3R5cGUgPSAiVW5zaWduZWQzMiI7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgVFlQRV9JTlRFR0VSMzI6CiAgICAgICAgICAgIHZhcl90eXBlID0gIkludGVnZXIzMiI7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgIHNwcmludGYodW5kZWZfbXNnLCAiVFlQRV8lZCIsIHRwLT50eXBlKTsKICAgICAgICAgICAgdmFyX3R5cGUgPSB1bmRlZl9tc2c7CiAgICAgICAgfQogICAgICAgIHNucHJpbnRmKGVycm9yX21zZywgc2l6ZW9mKGVycm9yX21zZyksCiAgICAgICAgICAgICAgICJUeXBlIG9mIGF0dHJpYnV0ZSBpcyAlcywgbm90ICVzIiwgdmFyX3R5cGUsIHZhbHVlKTsKICAgICAgICBlcnJvcl9tc2dbIHNpemVvZihlcnJvcl9tc2cpLTEgXSA9IDA7CiAgICAgICAgcmVzdWx0ID0gU05NUEVSUl9WQVJfVFlQRTsKICAgICAgICBzbm1wX3NldF9kZXRhaWwoZXJyb3JfbXNnKTsKICAgICAgICBnb3RvIG91dDsKICAgIH0KI2VuZGlmIC8qIE5FVFNOTVBfRElTQUJMRV9NSUJfTE9BRElORyAqLwogIGZhaWw6CiAgICByZXN1bHQgPSBTTk1QRVJSX1ZBTFVFOwogICAgc25tcF9zZXRfZGV0YWlsKHZhbHVlKTsKICBvdXQ6CiAgICBTRVRfU05NUF9FUlJPUihyZXN1bHQpOwogICAgcmV0dXJuIHJlc3VsdDsKfQoKLyoKICogcmV0dXJucyBOVUxMIG9yIGludGVybmFsIHBvaW50ZXIgdG8gc2Vzc2lvbgogKiB1c2UgdGhpcyBwb2ludGVyIGZvciB0aGUgb3RoZXIgc25tcF9zZXNzKiByb3V0aW5lcywKICogd2hpY2ggZ3VhcmFudGVlIGFjdGlvbiB3aWxsIG9jY3VyIE9OTFkgZm9yIHRoaXMgZ2l2ZW4gc2Vzc2lvbi4KICovCnZvaWQgICAgICAgICAgICoKc25tcF9zZXNzX3BvaW50ZXIobmV0c25tcF9zZXNzaW9uICogc2Vzc2lvbikKewogICAgc3RydWN0IHNlc3Npb25fbGlzdCAqc2xwOwoKICAgIHNubXBfcmVzX2xvY2soTVRfTElCUkFSWV9JRCwgTVRfTElCX1NFU1NJT04pOwogICAgZm9yIChzbHAgPSBTZXNzaW9uczsgc2xwOyBzbHAgPSBzbHAtPm5leHQpIHsKICAgICAgICBpZiAoc2xwLT5zZXNzaW9uID09IHNlc3Npb24pIHsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgfQogICAgfQogICAgc25tcF9yZXNfdW5sb2NrKE1UX0xJQlJBUllfSUQsIE1UX0xJQl9TRVNTSU9OKTsKCiAgICBpZiAoc2xwID09IE5VTEwpIHsKICAgICAgICBzbm1wX2Vycm5vID0gU05NUEVSUl9CQURfU0VTU0lPTjsgICAgICAgLypNVENSSVRJQ0FMX1JFU09VUkNFICovCiAgICAgICAgcmV0dXJuIChOVUxMKTsKICAgIH0KICAgIHJldHVybiAoKHZvaWQgKikgc2xwKTsKfQoKLyoKICogSW5wdXQgOiBhbiBvcGFxdWUgcG9pbnRlciwgcmV0dXJuZWQgYnkgc25tcF9zZXNzX29wZW4uCiAqIHJldHVybnMgTlVMTCBvciBwb2ludGVyIHRvIHNlc3Npb24uCiAqLwpuZXRzbm1wX3Nlc3Npb24gKgpzbm1wX3Nlc3Nfc2Vzc2lvbih2b2lkICpzZXNzcCkKewogICAgc3RydWN0IHNlc3Npb25fbGlzdCAqc2xwID0gKHN0cnVjdCBzZXNzaW9uX2xpc3QgKikgc2Vzc3A7CiAgICBpZiAoc2xwID09IE5VTEwpCiAgICAgICAgcmV0dXJuIChOVUxMKTsKICAgIHJldHVybiAoc2xwLT5zZXNzaW9uKTsKfQoKLyoqCiAqIExvb2sgdXAgYSBzZXNzaW9uIHRoYXQgYWxyZWFkeSBtYXkgaGF2ZSBiZWVuIGNsb3NlZC4KICoKICogQHBhcmFtIHNlc3NwIE9wYXF1ZSBwb2ludGVyLCByZXR1cm5lZCBieSBzbm1wX3Nlc3Nfb3Blbi4KICoKICogQHJldHVybiBQb2ludGVyIHRvIHNlc3Npb24gdXBvbiBzdWNjZXNzIG9yIE5VTEwgdXBvbiBmYWlsdXJlLgogKgogKiBAc2VlIHNubXBfc2Vzc19zZXNzaW9uKCkKICovCm5ldHNubXBfc2Vzc2lvbiAqCnNubXBfc2Vzc19zZXNzaW9uX2xvb2t1cCh2b2lkICpzZXNzcCkKewogICAgc3RydWN0IHNlc3Npb25fbGlzdCAqc2xwOwoKICAgIHNubXBfcmVzX2xvY2soTVRfTElCUkFSWV9JRCwgTVRfTElCX1NFU1NJT04pOwogICAgZm9yIChzbHAgPSBTZXNzaW9uczsgc2xwOyBzbHAgPSBzbHAtPm5leHQpIHsKICAgICAgICBpZiAoc2xwID09IHNlc3NwKSB7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIH0KICAgIH0KICAgIHNubXBfcmVzX3VubG9jayhNVF9MSUJSQVJZX0lELCBNVF9MSUJfU0VTU0lPTik7CgogICAgcmV0dXJuIChuZXRzbm1wX3Nlc3Npb24gKilzbHA7Cn0KCgovKgogKiBzbm1wX3Nlc3NfdHJhbnNwb3J0OiB0YWtlcyBhbiBvcGFxdWUgcG9pbnRlciAoYXMgcmV0dXJuZWQgYnkKICogc25tcF9zZXNzX29wZW4gb3Igc25tcF9zZXNzX3BvaW50ZXIpIGFuZCByZXR1cm5zIHRoZSBjb3JyZXNwb25kaW5nCiAqIG5ldHNubXBfdHJhbnNwb3J0IHBvaW50ZXIgKG9yIE5VTEwgaWYgdGhlIG9wYXF1ZSBwb2ludGVyIGRvZXMgbm90IGNvcnJlc3BvbmQKICogdG8gYW4gYWN0aXZlIGludGVybmFsIHNlc3Npb24pLiAgCiAqLwoKbmV0c25tcF90cmFuc3BvcnQgKgpzbm1wX3Nlc3NfdHJhbnNwb3J0KHZvaWQgKnNlc3NwKQp7CiAgICBzdHJ1Y3Qgc2Vzc2lvbl9saXN0ICpzbHAgPSAoc3RydWN0IHNlc3Npb25fbGlzdCAqKSBzZXNzcDsKICAgIGlmIChzbHAgPT0gTlVMTCkgewogICAgICAgIHJldHVybiBOVUxMOwogICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gc2xwLT50cmFuc3BvcnQ7CiAgICB9Cn0KCgoKLyoKICogc25tcF9zZXNzX3RyYW5zcG9ydF9zZXQ6IHNldCB0aGUgdHJhbnNwb3J0IHBvaW50ZXIgZm9yIHRoZSBvcGFxdWUKICogc2Vzc2lvbiBwb2ludGVyIHNwLiAgCiAqLwoKdm9pZApzbm1wX3Nlc3NfdHJhbnNwb3J0X3NldCh2b2lkICpzcCwgbmV0c25tcF90cmFuc3BvcnQgKnQpCnsKICAgIHN0cnVjdCBzZXNzaW9uX2xpc3QgKnNscCA9IChzdHJ1Y3Qgc2Vzc2lvbl9saXN0ICopIHNwOwogICAgaWYgKHNscCAhPSBOVUxMKSB7CiAgICAgICAgc2xwLT50cmFuc3BvcnQgPSB0OwogICAgfQp9CgoKLyoKICogc25tcF9kdXBsaWNhdGVfb2JqaWQ6IGR1cGxpY2F0ZXMgKG1hbGxvY3MpIGFuIG9iamlkIGJhc2VkIG9uIHRoZQogKiBpbnB1dCBvYmppZCAKICovCm9pZCAgICAgICAgICAgICoKc25tcF9kdXBsaWNhdGVfb2JqaWQoY29uc3Qgb2lkICogb2JqVG9Db3B5LCBzaXplX3Qgb2JqVG9Db3B5TGVuKQp7CiAgICBvaWQgICAgICAgICAgICAqcmV0dXJuT2lkID0gTlVMTDsKICAgIGlmIChvYmpUb0NvcHkgIT0gTlVMTCAmJiBvYmpUb0NvcHlMZW4gIT0gMCkgewogICAgICAgIHJldHVybk9pZCA9IChvaWQgKikgbWFsbG9jKG9ialRvQ29weUxlbiAqIHNpemVvZihvaWQpKTsKICAgICAgICBpZiAocmV0dXJuT2lkKSB7CiAgICAgICAgICAgIG1lbW1vdmUocmV0dXJuT2lkLCBvYmpUb0NvcHksIG9ialRvQ29weUxlbiAqIHNpemVvZihvaWQpKTsKICAgICAgICB9CiAgICB9CiAgICByZXR1cm4gcmV0dXJuT2lkOwp9CgovKgogKiBnZW5lcmljIHN0YXRpc3RpY3MgY291bnRlciBmdW5jdGlvbnMgCiAqLwpzdGF0aWMgdV9pbnQgICAgc3RhdGlzdGljc1tNQVhfU1RBVFNdOwoKdV9pbnQKc25tcF9pbmNyZW1lbnRfc3RhdGlzdGljKGludCB3aGljaCkKewogICAgaWYgKHdoaWNoID49IDAgJiYgd2hpY2ggPCBNQVhfU1RBVFMpIHsKICAgICAgICBzdGF0aXN0aWNzW3doaWNoXSsrOwogICAgICAgIHJldHVybiBzdGF0aXN0aWNzW3doaWNoXTsKICAgIH0KICAgIHJldHVybiAwOwp9Cgp1X2ludApzbm1wX2luY3JlbWVudF9zdGF0aXN0aWNfYnkoaW50IHdoaWNoLCBpbnQgY291bnQpCnsKICAgIGlmICh3aGljaCA+PSAwICYmIHdoaWNoIDwgTUFYX1NUQVRTKSB7CiAgICAgICAgc3RhdGlzdGljc1t3aGljaF0gKz0gY291bnQ7CiAgICAgICAgcmV0dXJuIHN0YXRpc3RpY3Nbd2hpY2hdOwogICAgfQogICAgcmV0dXJuIDA7Cn0KCnVfaW50CnNubXBfZ2V0X3N0YXRpc3RpYyhpbnQgd2hpY2gpCnsKICAgIGlmICh3aGljaCA+PSAwICYmIHdoaWNoIDwgTUFYX1NUQVRTKQogICAgICAgIHJldHVybiBzdGF0aXN0aWNzW3doaWNoXTsKICAgIHJldHVybiAwOwp9Cgp2b2lkCnNubXBfaW5pdF9zdGF0aXN0aWNzKHZvaWQpCnsKICAgIG1lbXNldChzdGF0aXN0aWNzLCAwLCBzaXplb2Yoc3RhdGlzdGljcykpOwp9Ci8qKiAgQH0gKi8KCg==