LyogbW9kaWZpZWQgYnkgTWFydGluIEhlZGVuZmFsayA8bWhlQHN0YWNrZW4ua3RoLnNlPiBmb3IgdXNlIGluIEN1cmwKICogbGFzdCBtb2RpZmllZCAyMDAwLTA5LTE4CiAqLwoKLyoKICogQ29weXJpZ2h0IChjKSAxOTk1LCAxOTk2LCAxOTk3LCAxOTk4LCAxOTk5IEt1bmdsaWdhIFRla25pc2thIEj2Z3Nrb2xhbgogKiAoUm95YWwgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIFN0b2NraG9sbSwgU3dlZGVuKS4KICogQWxsIHJpZ2h0cyByZXNlcnZlZC4KICogCiAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAogKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKICogYXJlIG1ldDoKICogCiAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CiAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KICogCiAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0CiAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbiB0aGUKICogICAgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlIGRpc3RyaWJ1dGlvbi4KICogCiAqIDMuIE5laXRoZXIgdGhlIG5hbWUgb2YgdGhlIEluc3RpdHV0ZSBub3IgdGhlIG5hbWVzIG9mIGl0cyBjb250cmlidXRvcnMKICogICAgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlCiAqICAgIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgogKiAKICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgSU5TVElUVVRFIEFORCBDT05UUklCVVRPUlMgYGBBUyBJUycnIEFORAogKiBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUKICogSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UKICogQVJFIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgSU5TVElUVVRFIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUKICogRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwKICogREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMKICogT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pCiAqIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUCiAqIExJQUJJTElUWSwgT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkKICogT1VUIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgogKiBTVUNIIERBTUFHRS4KICovCgojaW5jbHVkZSAic2V0dXAuaCIKCiNpZmRlZiBLUkI0CgojaW5jbHVkZSAic2VjdXJpdHkuaCIKI2luY2x1ZGUgImJhc2U2NC5oIgojaW5jbHVkZSA8c3RkbGliLmg+CiNpbmNsdWRlIDxuZXRkYi5oPgojaW5jbHVkZSA8c3lzbG9nLmg+CiNpbmNsdWRlIDxzdHJpbmcuaD4KI2luY2x1ZGUgPGtyYi5oPgoKLyogVGhlIGxhc3QgI2luY2x1ZGUgZmlsZSBzaG91bGQgYmU6ICovCiNpZmRlZiBNQUxMT0NERUJVRwojaW5jbHVkZSAibWVtZGVidWcuaCIKI2VuZGlmCgojaWZkZWYgRlRQX1NFUlZFUgojZGVmaW5lIExPQ0FMX0FERFIgY3RybF9hZGRyCiNkZWZpbmUgUkVNT1RFX0FERFIgaGlzX2FkZHIKI2Vsc2UKLyojZGVmaW5lIExPQ0FMX0FERFIgbXljdGxhZGRyKioqLwovKiNkZWZpbmUgUkVNT1RFX0FERFIgaGlzY3RsYWRkcioqKi8KI2VuZGlmCgovKmV4dGVybiBzdHJ1Y3Qgc29ja2FkZHIgKkxPQ0FMX0FERFIsICpSRU1PVEVfQUREUjsqKiovCgojZGVmaW5lIExPQ0FMX0FERFIgKCZsb2NhbF9hZGRyKQojZGVmaW5lIFJFTU9URV9BRERSICgmY29ubi0+c2Vydl9hZGRyKQojZGVmaW5lIG15Y3RsYWRkciBMT0NBTF9BRERSCiNkZWZpbmUgaGlzY3RsYWRkciBSRU1PVEVfQUREUgoKc3RhdGljIHN0cnVjdCBzb2NrYWRkcl9pbiBsb2NhbF9hZGRyOwoKc3RydWN0IGtyYjRfZGF0YSB7CiAgICBkZXNfY2Jsb2NrIGtleTsKICAgIGRlc19rZXlfc2NoZWR1bGUgc2NoZWR1bGU7CiAgICBjaGFyIG5hbWVbQU5BTUVfU1pdOwogICAgY2hhciBpbnN0YW5jZVtJTlNUX1NaXTsKICAgIGNoYXIgcmVhbG1bUkVBTE1fU1pdOwp9OwoKI2lmbmRlZiBIQVZFX1NUUkxDUFkKCnNpemVfdApzdHJsY3B5IChjaGFyICpkc3QsIGNvbnN0IGNoYXIgKnNyYywgc2l6ZV90IGRzdF9zeikKewogICAgc2l6ZV90IG47CiAgICBjaGFyICpwOwoKICAgIGZvciAocCA9IGRzdCwgbiA9IDA7CgkgbiArIDEgPCBkc3Rfc3ogJiYgKnNyYyAhPSAnXDAnOwoJICsrcCwgKytzcmMsICsrbikKCSpwID0gKnNyYzsKICAgICpwID0gJ1wwJzsKICAgIGlmICgqc3JjID09ICdcMCcpCglyZXR1cm4gbjsKICAgIGVsc2UKCXJldHVybiBuICsgc3RybGVuIChzcmMpOwp9CgojZW5kaWYKCnN0YXRpYyBpbnQKa3JiNF9jaGVja19wcm90KHZvaWQgKmFwcF9kYXRhLCBpbnQgbGV2ZWwpCnsKICAgIGlmKGxldmVsID09IHByb3RfY29uZmlkZW50aWFsKQoJcmV0dXJuIC0xOwogICAgcmV0dXJuIDA7Cn0KCnN0YXRpYyBpbnQKa3JiNF9kZWNvZGUodm9pZCAqYXBwX2RhdGEsIHZvaWQgKmJ1ZiwgaW50IGxlbiwgaW50IGxldmVsLAoJICAgIHN0cnVjdCBjb25uZWN0ZGF0YSAqY29ubikKewogICAgTVNHX0RBVCBtOwogICAgaW50IGU7CiAgICBzdHJ1Y3Qga3JiNF9kYXRhICpkID0gYXBwX2RhdGE7CiAgICAKICAgIGlmKGxldmVsID09IHByb3Rfc2FmZSkKCWUgPSBrcmJfcmRfc2FmZShidWYsIGxlbiwgJmQtPmtleSwKCQkJKHN0cnVjdCBzb2NrYWRkcl9pbiAqKVJFTU9URV9BRERSLAoJCQkoc3RydWN0IHNvY2thZGRyX2luICopTE9DQUxfQUREUiwgJm0pOwogICAgZWxzZQoJZSA9IGtyYl9yZF9wcml2KGJ1ZiwgbGVuLCBkLT5zY2hlZHVsZSwgJmQtPmtleSwgCgkJCShzdHJ1Y3Qgc29ja2FkZHJfaW4gKilSRU1PVEVfQUREUiwKCQkJKHN0cnVjdCBzb2NrYWRkcl9pbiAqKUxPQ0FMX0FERFIsICZtKTsKICAgIGlmKGUpewoJc3lzbG9nKExPR19FUlIsICJrcmI0X2RlY29kZTogJXMiLCBrcmJfZ2V0X2Vycl90ZXh0KGUpKTsKCXJldHVybiAtMTsKICAgIH0KICAgIG1lbW1vdmUoYnVmLCBtLmFwcF9kYXRhLCBtLmFwcF9sZW5ndGgpOwogICAgcmV0dXJuIG0uYXBwX2xlbmd0aDsKfQoKc3RhdGljIGludAprcmI0X292ZXJoZWFkKHZvaWQgKmFwcF9kYXRhLCBpbnQgbGV2ZWwsIGludCBsZW4pCnsKICAgIHJldHVybiAzMTsKfQoKc3RhdGljIGludAprcmI0X2VuY29kZSh2b2lkICphcHBfZGF0YSwgdm9pZCAqZnJvbSwgaW50IGxlbmd0aCwgaW50IGxldmVsLCB2b2lkICoqdG8sCgkgICAgc3RydWN0IGNvbm5lY3RkYXRhICpjb25uKQp7CiAgICBzdHJ1Y3Qga3JiNF9kYXRhICpkID0gYXBwX2RhdGE7CiAgICAqdG8gPSBtYWxsb2MobGVuZ3RoICsgMzEpOwogICAgaWYobGV2ZWwgPT0gcHJvdF9zYWZlKQoJcmV0dXJuIGtyYl9ta19zYWZlKGZyb20sICp0bywgbGVuZ3RoLCAmZC0+a2V5LCAKCQkJICAgKHN0cnVjdCBzb2NrYWRkcl9pbiAqKUxPQ0FMX0FERFIsCgkJCSAgIChzdHJ1Y3Qgc29ja2FkZHJfaW4gKilSRU1PVEVfQUREUik7CiAgICBlbHNlIGlmKGxldmVsID09IHByb3RfcHJpdmF0ZSkKCXJldHVybiBrcmJfbWtfcHJpdihmcm9tLCAqdG8sIGxlbmd0aCwgZC0+c2NoZWR1bGUsICZkLT5rZXksIAoJCQkgICAoc3RydWN0IHNvY2thZGRyX2luICopTE9DQUxfQUREUiwKCQkJICAgKHN0cnVjdCBzb2NrYWRkcl9pbiAqKVJFTU9URV9BRERSKTsKICAgIGVsc2UKCXJldHVybiAtMTsKfQoKI2lmZGVmIEZUUF9TRVJWRVIKCnN0YXRpYyBpbnQKa3JiNF9hZGF0KHZvaWQgKmFwcF9kYXRhLCB2b2lkICpidWYsIHNpemVfdCBsZW4pCnsKICAgIEtURVhUX1NUIHRrdDsKICAgIEFVVEhfREFUIGF1dGhfZGF0OwogICAgY2hhciAqcDsKICAgIGludCBrZXJyb3I7CiAgICB1X2ludDMyX3QgY3M7CiAgICBjaGFyIG1zZ1szNV07IC8qIHNpemUgb2YgZW5jcnlwdGVkIGJsb2NrICovCiAgICBpbnQgdG1wX2xlbjsKICAgIHN0cnVjdCBrcmI0X2RhdGEgKmQgPSBhcHBfZGF0YTsKICAgIGNoYXIgaW5zdFtJTlNUX1NaXTsKICAgIHN0cnVjdCBzb2NrYWRkcl9pbiAqaGlzX2FkZHJfc2luID0gKHN0cnVjdCBzb2NrYWRkcl9pbiAqKWhpc19hZGRyOwoKICAgIG1lbWNweSh0a3QuZGF0LCBidWYsIGxlbik7CiAgICB0a3QubGVuZ3RoID0gbGVuOwoKICAgIGtfZ2V0c29ja2luc3QoMCwgaW5zdCwgc2l6ZW9mKGluc3QpKTsKICAgIGtlcnJvciA9IGtyYl9yZF9yZXEoJnRrdCwgImZ0cCIsIGluc3QsIAoJCQloaXNfYWRkcl9zaW4tPnNpbl9hZGRyLnNfYWRkciwgJmF1dGhfZGF0LCAiIik7CiAgICBpZihrZXJyb3IgPT0gUkRfQVBfVU5ERUMpewoJa19nZXRzb2NraW5zdCgwLCBpbnN0LCBzaXplb2YoaW5zdCkpOwoJa2Vycm9yID0ga3JiX3JkX3JlcSgmdGt0LCAicmNtZCIsIGluc3QsIAoJCQkgICAgaGlzX2FkZHJfc2luLT5zaW5fYWRkci5zX2FkZHIsICZhdXRoX2RhdCwgIiIpOwogICAgfQoKICAgIGlmKGtlcnJvcil7CglyZXBseSg1MzUsICJFcnJvciByZWFkaW5nIHJlcXVlc3Q6ICVzLiIsIGtyYl9nZXRfZXJyX3RleHQoa2Vycm9yKSk7CglyZXR1cm4gLTE7CiAgICB9CiAgICAKICAgIG1lbWNweShkLT5rZXksIGF1dGhfZGF0LnNlc3Npb24sIHNpemVvZihkLT5rZXkpKTsKICAgIGRlc19zZXRfa2V5KCZkLT5rZXksIGQtPnNjaGVkdWxlKTsKCiAgICBzdHJsY3B5KGQtPm5hbWUsIGF1dGhfZGF0LnBuYW1lLCBzaXplb2YoZC0+bmFtZSkpOwogICAgc3RybGNweShkLT5pbnN0YW5jZSwgYXV0aF9kYXQucGluc3QsIHNpemVvZihkLT5pbnN0YW5jZSkpOwogICAgc3RybGNweShkLT5yZWFsbSwgYXV0aF9kYXQucHJlYWxtLCBzaXplb2YoZC0+aW5zdGFuY2UpKTsKCiAgICBjcyA9IGF1dGhfZGF0LmNoZWNrc3VtICsgMTsKICAgIHsKCXVuc2lnbmVkIGNoYXIgdG1wWzRdOwoJS1JCX1BVVF9JTlQoY3MsIHRtcCwgNCwgc2l6ZW9mKHRtcCkpOwoJdG1wX2xlbiA9IGtyYl9ta19zYWZlKHRtcCwgbXNnLCA0LCAmZC0+a2V5LAoJCQkgICAgICAoc3RydWN0IHNvY2thZGRyX2luICopTE9DQUxfQUREUiwKCQkJICAgICAgKHN0cnVjdCBzb2NrYWRkcl9pbiAqKVJFTU9URV9BRERSKTsKICAgIH0KICAgIGlmKHRtcF9sZW4gPCAwKXsKCXJlcGx5KDUzNSwgIkVycm9yIGNyZWF0aW5nIHJlcGx5OiAlcy4iLCBzdHJlcnJvcihlcnJubykpOwoJcmV0dXJuIC0xOwogICAgfQogICAgbGVuID0gdG1wX2xlbjsKICAgIGlmKGJhc2U2NF9lbmNvZGUobXNnLCBsZW4sICZwKSA8IDApIHsKCXJlcGx5KDUzNSwgIk91dCBvZiBtZW1vcnkgYmFzZTY0LWVuY29kaW5nLiIpOwoJcmV0dXJuIC0xOwogICAgfQogICAgcmVwbHkoMjM1LCAiQURBVD0lcyIsIHApOwogICAgc2VjX2NvbXBsZXRlID0gMTsKICAgIGZyZWUocCk7CiAgICByZXR1cm4gMDsKfQoKc3RhdGljIGludAprcmI0X3VzZXJvayh2b2lkICphcHBfZGF0YSwgY2hhciAqdXNlcikKewogICAgc3RydWN0IGtyYjRfZGF0YSAqZCA9IGFwcF9kYXRhOwogICAgcmV0dXJuIGtyYl9rdXNlcm9rKGQtPm5hbWUsIGQtPmluc3RhbmNlLCBkLT5yZWFsbSwgdXNlcik7Cn0KCnN0cnVjdCBzZWNfc2VydmVyX21lY2gga3JiNF9zZXJ2ZXJfbWVjaCA9IHsKICAgICJLRVJCRVJPU19WNCIsCiAgICBzaXplb2Yoc3RydWN0IGtyYjRfZGF0YSksCiAgICBOVUxMLCAvKiBpbml0ICovCiAgICBOVUxMLCAvKiBlbmQgKi8KICAgIGtyYjRfY2hlY2tfcHJvdCwKICAgIGtyYjRfb3ZlcmhlYWQsCiAgICBrcmI0X2VuY29kZSwKICAgIGtyYjRfZGVjb2RlLAogICAgLyogKi8KICAgIE5VTEwsCiAgICBrcmI0X2FkYXQsCiAgICBOVUxMLCAvKiBwYnN6ICovCiAgICBOVUxMLCAvKiBjY2MgKi8KICAgIGtyYjRfdXNlcm9rCn07CgojZWxzZSAvKiBGVFBfU0VSVkVSICovCgpzdGF0aWMgaW50Cm1rX2F1dGgoc3RydWN0IGtyYjRfZGF0YSAqZCwgS1RFWFQgYWRhdCwgCgljaGFyICpzZXJ2aWNlLCBjaGFyICpob3N0LCBpbnQgY2hlY2tzdW0pCnsKICAgIGludCByZXQ7CiAgICBDUkVERU5USUFMUyBjcmVkOwogICAgY2hhciBzbmFtZVtTTkFNRV9TWl0sIGluc3RbSU5TVF9TWl0sIHJlYWxtW1JFQUxNX1NaXTsKCiAgICBzdHJsY3B5KHNuYW1lLCBzZXJ2aWNlLCBzaXplb2Yoc25hbWUpKTsKICAgIHN0cmxjcHkoaW5zdCwga3JiX2dldF9waG9zdChob3N0KSwgc2l6ZW9mKGluc3QpKTsKICAgIHN0cmxjcHkocmVhbG0sIGtyYl9yZWFsbW9maG9zdChob3N0KSwgc2l6ZW9mKHJlYWxtKSk7CiAgICByZXQgPSBrcmJfbWtfcmVxKGFkYXQsIHNuYW1lLCBpbnN0LCByZWFsbSwgY2hlY2tzdW0pOwogICAgaWYocmV0KQoJcmV0dXJuIHJldDsKICAgIHN0cmxjcHkoc25hbWUsIHNlcnZpY2UsIHNpemVvZihzbmFtZSkpOwogICAgc3RybGNweShpbnN0LCBrcmJfZ2V0X3Bob3N0KGhvc3QpLCBzaXplb2YoaW5zdCkpOwogICAgc3RybGNweShyZWFsbSwga3JiX3JlYWxtb2Zob3N0KGhvc3QpLCBzaXplb2YocmVhbG0pKTsKICAgIHJldCA9IGtyYl9nZXRfY3JlZChzbmFtZSwgaW5zdCwgcmVhbG0sICZjcmVkKTsKICAgIG1lbW1vdmUoJmQtPmtleSwgJmNyZWQuc2Vzc2lvbiwgc2l6ZW9mKGRlc19jYmxvY2spKTsKICAgIGRlc19rZXlfc2NoZWQoJmQtPmtleSwgZC0+c2NoZWR1bGUpOwogICAgbWVtc2V0KCZjcmVkLCAwLCBzaXplb2YoY3JlZCkpOwogICAgcmV0dXJuIHJldDsKfQoKc3RhdGljIGludAprcmI0X2F1dGgodm9pZCAqYXBwX2RhdGEsIHN0cnVjdCBjb25uZWN0ZGF0YSAqY29ubikKewogICAgaW50IHJldDsKICAgIGNoYXIgKnA7CiAgICBpbnQgbGVuOwogICAgS1RFWFRfU1QgYWRhdDsKICAgIE1TR19EQVQgbXNnX2RhdGE7CiAgICBpbnQgY2hlY2tzdW07CiAgICB1X2ludDMyX3QgY3M7CiAgICBzdHJ1Y3Qga3JiNF9kYXRhICpkID0gYXBwX2RhdGE7CiAgICBzdHJ1Y3Qgc29ja2FkZHJfaW4gKmxvY2FsYWRkciAgPSAoc3RydWN0IHNvY2thZGRyX2luICopTE9DQUxfQUREUjsKICAgIHN0cnVjdCBzb2NrYWRkcl9pbiAqcmVtb3RlYWRkciA9IChzdHJ1Y3Qgc29ja2FkZHJfaW4gKilSRU1PVEVfQUREUjsKICAgIGNoYXIgKmhvc3QgPSBjb25uLT5ocC0+aF9uYW1lOwogICAgc2l6ZV90IG5yZWFkOwogICAgaW50IGwgPSBzaXplb2YobG9jYWxfYWRkcik7CgogICAgaWYoZ2V0c29ja25hbWUoY29ubi0+ZGF0YS0+Zmlyc3Rzb2NrZXQsIExPQ0FMX0FERFIsICZsKSA8IDApCglwZXJyb3IoImdldHNvY2tuYW1lKCkiKTsKCiAgICBjaGVja3N1bSA9IGdldHBpZCgpOwogICAgcmV0ID0gbWtfYXV0aChkLCAmYWRhdCwgImZ0cCIsIGhvc3QsIGNoZWNrc3VtKTsKICAgIGlmKHJldCA9PSBLRENfUFJfVU5LTk9XTikKCXJldCA9IG1rX2F1dGgoZCwgJmFkYXQsICJyY21kIiwgaG9zdCwgY2hlY2tzdW0pOwogICAgaWYocmV0KXsKCXByaW50ZigiJXNcbiIsIGtyYl9nZXRfZXJyX3RleHQocmV0KSk7CglyZXR1cm4gQVVUSF9DT05USU5VRTsKICAgIH0KCiNpZmRlZiBIQVZFX0tSQl9HRVRfT1VSX0lQX0ZPUl9SRUFMTQogICAgaWYgKGtyYl9nZXRfY29uZmlnX2Jvb2woIm5hdF9pbl91c2UiKSkgewogICAgICBzdHJ1Y3QgaW5fYWRkciBuYXRBZGRyOwoKICAgICAgaWYgKGtyYl9nZXRfb3VyX2lwX2Zvcl9yZWFsbShrcmJfcmVhbG1vZmhvc3QoaG9zdCksCgkJCQkgICAmbmF0QWRkcikgIT0gS1NVQ0NFU1MKCSAgJiYga3JiX2dldF9vdXJfaXBfZm9yX3JlYWxtKE5VTEwsICZuYXRBZGRyKSAhPSBLU1VDQ0VTUykKCXByaW50ZigiQ2FuJ3QgZ2V0IGFkZHJlc3MgZm9yIHJlYWxtICVzXG4iLAoJICAgICAgIGtyYl9yZWFsbW9maG9zdChob3N0KSk7CiAgICAgIGVsc2UgewoJaWYgKG5hdEFkZHIuc19hZGRyICE9IGxvY2FsYWRkci0+c2luX2FkZHIuc19hZGRyKSB7CgkgIHByaW50ZigiVXNpbmcgTkFUIElQIGFkZHJlc3MgKCVzKSBmb3Iga2VyYmVyb3MgNFxuIiwKCQkgaW5ldF9udG9hKG5hdEFkZHIpKTsKCSAgbG9jYWxhZGRyLT5zaW5fYWRkciA9IG5hdEFkZHI7CgkgIAoJICAvKgoJICAgKiBUaGlzIG5vdCB0aGUgYmVzdCBwbGFjZSB0byBkbyB0aGlzLCBidXQgaXQKCSAgICogaXMgaGVyZSB3ZSBrbm93IHRoYXQgKHByb2JhYmx5KSBOQVQgaXMgaW4KCSAgICogdXNlIQoJICAgKi8KCgkgIC8qcGFzc2l2ZW1vZGUgPSAxOyoqKi8KCSAgLypwcmludGYoIlNldHRpbmc6IFBhc3NpdmUgbW9kZSBvbi5cbiIpOyoqKi8KCX0KICAgICAgfQogICAgfQojZW5kaWYKCiAgICAvKnByaW50ZigiTG9jYWwgYWRkcmVzcyBpcyAlc1xuIiwgaW5ldF9udG9hKGxvY2FsYWRkci0+c2luX2FkZHIpKTsqKiovCiAgICAvKnByaW50ZigiUmVtb3RlIGFkZHJlc3MgaXMgJXNcbiIsIGluZXRfbnRvYShyZW1vdGVhZGRyLT5zaW5fYWRkcikpOyoqKi8KCiAgICBpZihiYXNlNjRfZW5jb2RlKGFkYXQuZGF0LCBhZGF0Lmxlbmd0aCwgJnApIDwgMCkgewoJcHJpbnRmKCJPdXQgb2YgbWVtb3J5IGJhc2U2NC1lbmNvZGluZy5cbiIpOwoJcmV0dXJuIEFVVEhfQ09OVElOVUU7CiAgICB9CiAgICAvKnJldCA9IGNvbW1hbmQoIkFEQVQgJXMiLCBwKSovCiAgICBmdHBzZW5kZihjb25uLT5kYXRhLT5maXJzdHNvY2tldCwgY29ubiwgIkFEQVQgJXMiLCBwKTsKICAgIC8qIHdhaXQgZm9yIGZlZWRiYWNrICovCiAgICBucmVhZCA9IEdldExhc3RSZXNwb25zZShjb25uLT5kYXRhLT5maXJzdHNvY2tldCwKCQkJICAgIGNvbm4tPmRhdGEtPmJ1ZmZlciwgY29ubik7CiAgICBpZihucmVhZCA8IDApCglyZXR1cm4gLypDVVJMRV9PUEVSQVRJT05fVElNRU9VVEVEKi8tMTsKICAgIGZyZWUocCk7CgogICAgaWYoLypyZXQgIT0gQ09NUExFVEUqL2Nvbm4tPmRhdGEtPmJ1ZmZlclswXSAhPSAnMicpewoJcHJpbnRmKCJTZXJ2ZXIgZGlkbid0IGFjY2VwdCBhdXRoIGRhdGEuXG4iKTsKCXJldHVybiBBVVRIX0VSUk9SOwogICAgfQoKICAgIHAgPSBzdHJzdHIoLypyZXBseV9zdHJpbmcqL2Nvbm4tPmRhdGEtPmJ1ZmZlciwgIkFEQVQ9Iik7CiAgICBpZighcCl7CglwcmludGYoIlJlbW90ZSBob3N0IGRpZG4ndCBzZW5kIGFkYXQgcmVwbHkuXG4iKTsKCXJldHVybiBBVVRIX0VSUk9SOwogICAgfQogICAgcCArPSA1OwogICAgbGVuID0gYmFzZTY0X2RlY29kZShwLCBhZGF0LmRhdCk7CiAgICBpZihsZW4gPCAwKXsKCXByaW50ZigiRmFpbGVkIHRvIGRlY29kZSBiYXNlNjQgZnJvbSBzZXJ2ZXIuXG4iKTsKCXJldHVybiBBVVRIX0VSUk9SOwogICAgfQogICAgYWRhdC5sZW5ndGggPSBsZW47CiAgICByZXQgPSBrcmJfcmRfc2FmZShhZGF0LmRhdCwgYWRhdC5sZW5ndGgsICZkLT5rZXksIAoJCSAgICAgIChzdHJ1Y3Qgc29ja2FkZHJfaW4gKiloaXNjdGxhZGRyLCAKCQkgICAgICAoc3RydWN0IHNvY2thZGRyX2luICopbXljdGxhZGRyLCAmbXNnX2RhdGEpOwogICAgaWYocmV0KXsKCXByaW50ZigiRXJyb3IgcmVhZGluZyByZXBseSBmcm9tIHNlcnZlcjogJXMuXG4iLCAKCSAgICAgICBrcmJfZ2V0X2Vycl90ZXh0KHJldCkpOwoJcmV0dXJuIEFVVEhfRVJST1I7CiAgICB9CiAgICBrcmJfZ2V0X2ludChtc2dfZGF0YS5hcHBfZGF0YSwgJmNzLCA0LCAwKTsKICAgIGlmKGNzIC0gY2hlY2tzdW0gIT0gMSl7CglwcmludGYoIkJhZCBjaGVja3N1bSByZXR1cm5lZCBmcm9tIHNlcnZlci5cbiIpOwoJcmV0dXJuIEFVVEhfRVJST1I7CiAgICB9CiAgICByZXR1cm4gQVVUSF9PSzsKfQoKc3RydWN0IHNlY19jbGllbnRfbWVjaCBrcmI0X2NsaWVudF9tZWNoID0gewogICAgIktFUkJFUk9TX1Y0IiwKICAgIHNpemVvZihzdHJ1Y3Qga3JiNF9kYXRhKSwKICAgIE5VTEwsIC8qIGluaXQgKi8KICAgIGtyYjRfYXV0aCwKICAgIE5VTEwsIC8qIGVuZCAqLwogICAga3JiNF9jaGVja19wcm90LAogICAga3JiNF9vdmVyaGVhZCwKICAgIGtyYjRfZW5jb2RlLAogICAga3JiNF9kZWNvZGUKfTsKCiNlbmRpZiAvKiBGVFBfU0VSVkVSICovCgp2b2lkIGtyYl9rYXV0aChzdHJ1Y3QgY29ubmVjdGRhdGEgKmNvbm4pCnsKICAgIGludCByZXQ7CiAgICBjaGFyIGJ1ZlsxMDI0XTsKICAgIGRlc19jYmxvY2sga2V5OwogICAgZGVzX2tleV9zY2hlZHVsZSBzY2hlZHVsZTsKICAgIEtURVhUX1NUIHRrdCwgdGt0Y29weTsKICAgIGNoYXIgKm5hbWU7CiAgICBjaGFyICpwOwogICAgaW50IG92ZXJib3NlOwogICAgY2hhciBwYXNzd2RbMTAwXTsKICAgIGludCB0bXA7CiAgICBzaXplX3QgbnJlYWQ7CgkKICAgIGludCBzYXZlOwoKICAgIHNhdmUgPSBzZXRfY29tbWFuZF9wcm90KGNvbm4sIHByb3RfcHJpdmF0ZSk7CiAgICAvKnJldCA9IGNvbW1hbmQoIlNJVEUgS0FVVEggJXMiLCBuYW1lKTsqKiovCiAgICBmdHBzZW5kZihjb25uLT5kYXRhLT5maXJzdHNvY2tldCwgY29ubiwKICAgICAgICAgICAgICJTSVRFIEtBVVRIICVzIiwgY29ubi0+ZGF0YS0+dXNlcik7CiAgICAvKiB3YWl0IGZvciBmZWVkYmFjayAqLwogICAgbnJlYWQgPSBHZXRMYXN0UmVzcG9uc2UoY29ubi0+ZGF0YS0+Zmlyc3Rzb2NrZXQsIGNvbm4tPmRhdGEtPmJ1ZmZlciwgY29ubik7CiAgICBpZihucmVhZCA8IDApCglyZXR1cm4gLypDVVJMRV9PUEVSQVRJT05fVElNRU9VVEVEKi87CgogICAgaWYoLypyZXQgIT0gQ09OVElOVUUqL2Nvbm4tPmRhdGEtPmJ1ZmZlclswXSAhPSAnMycpewoJLyp2ZXJib3NlID0gb3ZlcmJvc2U7KioqLwoJc2V0X2NvbW1hbmRfcHJvdChjb25uLCBzYXZlKTsKCS8qY29kZSA9IC0xOyoqKi8KCXJldHVybjsKICAgIH0KICAgIC8qdmVyYm9zZSA9IG92ZXJib3NlOyoqKi8KICAgIHAgPSBzdHJzdHIoLypyZXBseV9zdHJpbmcqKiovY29ubi0+ZGF0YS0+YnVmZmVyLCAiVD0iKTsKICAgIGlmKCFwKXsKCXByaW50ZigiQmFkIHJlcGx5IGZyb20gc2VydmVyLlxuIik7CglzZXRfY29tbWFuZF9wcm90KGNvbm4sIHNhdmUpOwoJLypjb2RlID0gLTE7KioqLwoJcmV0dXJuOwogICAgfQogICAgcCArPSAyOwogICAgdG1wID0gYmFzZTY0X2RlY29kZShwLCAmdGt0LmRhdCk7CiAgICBpZih0bXAgPCAwKXsKCXByaW50ZigiRmFpbGVkIHRvIGRlY29kZSBiYXNlNjQgaW4gcmVwbHkuXG4iKTsKCXNldF9jb21tYW5kX3Byb3QoY29ubiwgc2F2ZSk7CgkvKmNvZGUgPSAtMTsqKiovCglyZXR1cm47CiAgICB9CiAgICB0a3QubGVuZ3RoID0gdG1wOwogICAgdGt0Y29weS5sZW5ndGggPSB0a3QubGVuZ3RoOwogICAgCiAgICBwID0gc3Ryc3RyKC8qcmVwbHlfc3RyaW5nKioqL2Nvbm4tPmRhdGEtPmJ1ZmZlciwgIlA9Iik7CiAgICBpZighcCl7CglwcmludGYoIkJhZCByZXBseSBmcm9tIHNlcnZlci5cbiIpOwoJLyp2ZXJib3NlID0gb3ZlcmJvc2U7KioqLwoJc2V0X2NvbW1hbmRfcHJvdChjb25uLCBzYXZlKTsKCS8qY29kZSA9IC0xOyoqKi8KCXJldHVybjsKICAgIH0KICAgIG5hbWUgPSBwICsgMjsKICAgIGZvcig7ICpwICYmICpwICE9ICcgJyAmJiAqcCAhPSAnXHInICYmICpwICE9ICdcbic7IHArKyk7CiAgICAqcCA9IDA7CgojaWYgMAogICAgc25wcmludGYoYnVmLCBzaXplb2YoYnVmKSwgIlBhc3N3b3JkIGZvciAlczoiLCBuYW1lKTsKICAgIGlmIChkZXNfcmVhZF9wd19zdHJpbmcgKHBhc3N3ZCwgc2l6ZW9mKHBhc3N3ZCktMSwgYnVmLCAwKSkKICAgICAgICAqcGFzc3dkID0gJ1wwJzsKICAgIGRlc19zdHJpbmdfdG9fa2V5IChwYXNzd2QsICZrZXkpOwojZWxzZQogICAgZGVzX3N0cmluZ190b19rZXkgKGNvbm4tPmRhdGEtPnBhc3N3ZCwgJmtleSk7CiNlbmRpZgoKICAgIGRlc19rZXlfc2NoZWQoJmtleSwgc2NoZWR1bGUpOwogICAgCiAgICBkZXNfcGNiY19lbmNyeXB0KChkZXNfY2Jsb2NrKil0a3QuZGF0LCAoZGVzX2NibG9jayopdGt0Y29weS5kYXQsCgkJICAgICB0a3QubGVuZ3RoLAoJCSAgICAgc2NoZWR1bGUsICZrZXksIERFU19ERUNSWVBUKTsKICAgIGlmIChzdHJjbXAgKChjaGFyKil0a3Rjb3B5LmRhdCArIDgsCgkJS1JCX1RJQ0tFVF9HUkFOVElOR19USUNLRVQpICE9IDApIHsKICAgICAgICBhZnNfc3RyaW5nX3RvX2tleSAocGFzc3dkLAoJCQkgICBrcmJfcmVhbG1vZmhvc3QoLypob3N0bmFtZSoqKi9jb25uLT5ocC0+aF9uYW1lKSwKCQkJICAgJmtleSk7CglkZXNfa2V5X3NjaGVkICgma2V5LCBzY2hlZHVsZSk7CglkZXNfcGNiY19lbmNyeXB0KChkZXNfY2Jsb2NrKil0a3QuZGF0LCAoZGVzX2NibG9jayopdGt0Y29weS5kYXQsCgkJCSB0a3QubGVuZ3RoLAoJCQkgc2NoZWR1bGUsICZrZXksIERFU19ERUNSWVBUKTsKICAgIH0KICAgIG1lbXNldChrZXksIDAsIHNpemVvZihrZXkpKTsKICAgIG1lbXNldChzY2hlZHVsZSwgMCwgc2l6ZW9mKHNjaGVkdWxlKSk7CiAgICBtZW1zZXQocGFzc3dkLCAwLCBzaXplb2YocGFzc3dkKSk7CiAgICBpZihiYXNlNjRfZW5jb2RlKHRrdGNvcHkuZGF0LCB0a3Rjb3B5Lmxlbmd0aCwgJnApIDwgMCkgewogICAgICBmYWlsZihjb25uLT5kYXRhLCAiT3V0IG9mIG1lbW9yeSBiYXNlNjQtZW5jb2RpbmcuXG4iKTsKICAgICAgc2V0X2NvbW1hbmRfcHJvdChjb25uLCBzYXZlKTsKICAgICAgLypjb2RlID0gLTE7KioqLwogICAgICByZXR1cm47CiAgICB9CiAgICBtZW1zZXQgKHRrdGNvcHkuZGF0LCAwLCB0a3Rjb3B5Lmxlbmd0aCk7CiAgICAvKnJldCA9IGNvbW1hbmQoIlNJVEUgS0FVVEggJXMgJXMiLCBuYW1lLCBwKTsqKiovCiAgICBmdHBzZW5kZihjb25uLT5kYXRhLT5maXJzdHNvY2tldCwgY29ubiwKICAgICAgICAgICAgICJTSVRFIEtBVVRIICVzICVzIiwgbmFtZSwgcCk7CiAgICAvKiB3YWl0IGZvciBmZWVkYmFjayAqLwogICAgbnJlYWQgPSBHZXRMYXN0UmVzcG9uc2UoY29ubi0+ZGF0YS0+Zmlyc3Rzb2NrZXQsIGNvbm4tPmRhdGEtPmJ1ZmZlciwgY29ubik7CiAgICBpZihucmVhZCA8IDApCglyZXR1cm4gLypDVVJMRV9PUEVSQVRJT05fVElNRU9VVEVEKi87CiAgICBmcmVlKHApOwogICAgc2V0X2NvbW1hbmRfcHJvdChjb25uLCBzYXZlKTsKfQoKI2VuZGlmIC8qIEtSQjQgKi8K