LyogbW9kaWZpZWQgYnkgTWFydGluIEhlZGVuZmFsayA8bWhlQHN0YWNrZW4ua3RoLnNlPiBmb3IgdXNlIGluIEN1cmwKICogbGFzdCBtb2RpZmllZCAyMDAwLTA5LTE4CiAqLwoKLyoKICogQ29weXJpZ2h0IChjKSAxOTk1LCAxOTk2LCAxOTk3LCAxOTk4LCAxOTk5IEt1bmdsaWdhIFRla25pc2thIEj2Z3Nrb2xhbgogKiAoUm95YWwgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIFN0b2NraG9sbSwgU3dlZGVuKS4KICogQWxsIHJpZ2h0cyByZXNlcnZlZC4KICogCiAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAogKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKICogYXJlIG1ldDoKICogCiAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CiAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KICogCiAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0CiAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbiB0aGUKICogICAgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlIGRpc3RyaWJ1dGlvbi4KICogCiAqIDMuIE5laXRoZXIgdGhlIG5hbWUgb2YgdGhlIEluc3RpdHV0ZSBub3IgdGhlIG5hbWVzIG9mIGl0cyBjb250cmlidXRvcnMKICogICAgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlCiAqICAgIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgogKiAKICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgSU5TVElUVVRFIEFORCBDT05UUklCVVRPUlMgYGBBUyBJUycnIEFORAogKiBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUKICogSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UKICogQVJFIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgSU5TVElUVVRFIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUKICogRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwKICogREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMKICogT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pCiAqIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUCiAqIExJQUJJTElUWSwgT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkKICogT1VUIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgogKiBTVUNIIERBTUFHRS4KICovCgojaW5jbHVkZSAic2V0dXAuaCIKCiNpZmRlZiBLUkI0CgojaW5jbHVkZSAic2VjdXJpdHkuaCIKI2luY2x1ZGUgImJhc2U2NC5oIgojaW5jbHVkZSA8c3RkbGliLmg+CiNpbmNsdWRlIDxuZXRkYi5oPgojaW5jbHVkZSA8c3lzbG9nLmg+CiNpbmNsdWRlIDxzdHJpbmcuaD4KI2luY2x1ZGUgPGtyYi5oPgoKI2luY2x1ZGUgImZ0cC5oIgojaW5jbHVkZSAic2VuZGYuaCIKCi8qIFRoZSBsYXN0ICNpbmNsdWRlIGZpbGUgc2hvdWxkIGJlOiAqLwojaWZkZWYgTUFMTE9DREVCVUcKI2luY2x1ZGUgIm1lbWRlYnVnLmgiCiNlbmRpZgoKI2lmZGVmIEZUUF9TRVJWRVIKI2RlZmluZSBMT0NBTF9BRERSIGN0cmxfYWRkcgojZGVmaW5lIFJFTU9URV9BRERSIGhpc19hZGRyCiNlbHNlCi8qI2RlZmluZSBMT0NBTF9BRERSIG15Y3RsYWRkcioqKi8KLyojZGVmaW5lIFJFTU9URV9BRERSIGhpc2N0bGFkZHIqKiovCiNlbmRpZgoKLypleHRlcm4gc3RydWN0IHNvY2thZGRyICpMT0NBTF9BRERSLCAqUkVNT1RFX0FERFI7KioqLwoKI2RlZmluZSBMT0NBTF9BRERSICgmbG9jYWxfYWRkcikKI2RlZmluZSBSRU1PVEVfQUREUiAoJmNvbm4tPnNlcnZfYWRkcikKI2RlZmluZSBteWN0bGFkZHIgTE9DQUxfQUREUgojZGVmaW5lIGhpc2N0bGFkZHIgUkVNT1RFX0FERFIKCnN0YXRpYyBzdHJ1Y3Qgc29ja2FkZHJfaW4gbG9jYWxfYWRkcjsKCnN0cnVjdCBrcmI0X2RhdGEgewogICAgZGVzX2NibG9jayBrZXk7CiAgICBkZXNfa2V5X3NjaGVkdWxlIHNjaGVkdWxlOwogICAgY2hhciBuYW1lW0FOQU1FX1NaXTsKICAgIGNoYXIgaW5zdGFuY2VbSU5TVF9TWl07CiAgICBjaGFyIHJlYWxtW1JFQUxNX1NaXTsKfTsKCiNpZm5kZWYgSEFWRV9TVFJMQ1BZCgpzaXplX3QKc3RybGNweSAoY2hhciAqZHN0LCBjb25zdCBjaGFyICpzcmMsIHNpemVfdCBkc3Rfc3opCnsKICAgIHNpemVfdCBuOwogICAgY2hhciAqcDsKCiAgICBmb3IgKHAgPSBkc3QsIG4gPSAwOwoJIG4gKyAxIDwgZHN0X3N6ICYmICpzcmMgIT0gJ1wwJzsKCSArK3AsICsrc3JjLCArK24pCgkqcCA9ICpzcmM7CiAgICAqcCA9ICdcMCc7CiAgICBpZiAoKnNyYyA9PSAnXDAnKQoJcmV0dXJuIG47CiAgICBlbHNlCglyZXR1cm4gbiArIHN0cmxlbiAoc3JjKTsKfQojZWxzZQpzaXplX3Qgc3RybGNweSAoY2hhciAqZHN0LCBjb25zdCBjaGFyICpzcmMsIHNpemVfdCBkc3Rfc3opOwojZW5kaWYKCnN0YXRpYyBpbnQKa3JiNF9jaGVja19wcm90KHZvaWQgKmFwcF9kYXRhLCBpbnQgbGV2ZWwpCnsKICAgIGlmKGxldmVsID09IHByb3RfY29uZmlkZW50aWFsKQoJcmV0dXJuIC0xOwogICAgcmV0dXJuIDA7Cn0KCnN0YXRpYyBpbnQKa3JiNF9kZWNvZGUodm9pZCAqYXBwX2RhdGEsIHZvaWQgKmJ1ZiwgaW50IGxlbiwgaW50IGxldmVsLAoJICAgIHN0cnVjdCBjb25uZWN0ZGF0YSAqY29ubikKewogICAgTVNHX0RBVCBtOwogICAgaW50IGU7CiAgICBzdHJ1Y3Qga3JiNF9kYXRhICpkID0gYXBwX2RhdGE7CiAgICAKICAgIGlmKGxldmVsID09IHByb3Rfc2FmZSkKCWUgPSBrcmJfcmRfc2FmZShidWYsIGxlbiwgJmQtPmtleSwKCQkJKHN0cnVjdCBzb2NrYWRkcl9pbiAqKVJFTU9URV9BRERSLAoJCQkoc3RydWN0IHNvY2thZGRyX2luICopTE9DQUxfQUREUiwgJm0pOwogICAgZWxzZQoJZSA9IGtyYl9yZF9wcml2KGJ1ZiwgbGVuLCBkLT5zY2hlZHVsZSwgJmQtPmtleSwgCgkJCShzdHJ1Y3Qgc29ja2FkZHJfaW4gKilSRU1PVEVfQUREUiwKCQkJKHN0cnVjdCBzb2NrYWRkcl9pbiAqKUxPQ0FMX0FERFIsICZtKTsKICAgIGlmKGUpewoJc3lzbG9nKExPR19FUlIsICJrcmI0X2RlY29kZTogJXMiLCBrcmJfZ2V0X2Vycl90ZXh0KGUpKTsKCXJldHVybiAtMTsKICAgIH0KICAgIG1lbW1vdmUoYnVmLCBtLmFwcF9kYXRhLCBtLmFwcF9sZW5ndGgpOwogICAgcmV0dXJuIG0uYXBwX2xlbmd0aDsKfQoKc3RhdGljIGludAprcmI0X292ZXJoZWFkKHZvaWQgKmFwcF9kYXRhLCBpbnQgbGV2ZWwsIGludCBsZW4pCnsKICAgIHJldHVybiAzMTsKfQoKc3RhdGljIGludAprcmI0X2VuY29kZSh2b2lkICphcHBfZGF0YSwgdm9pZCAqZnJvbSwgaW50IGxlbmd0aCwgaW50IGxldmVsLCB2b2lkICoqdG8sCgkgICAgc3RydWN0IGNvbm5lY3RkYXRhICpjb25uKQp7CiAgICBzdHJ1Y3Qga3JiNF9kYXRhICpkID0gYXBwX2RhdGE7CiAgICAqdG8gPSBtYWxsb2MobGVuZ3RoICsgMzEpOwogICAgaWYobGV2ZWwgPT0gcHJvdF9zYWZlKQoJcmV0dXJuIGtyYl9ta19zYWZlKGZyb20sICp0bywgbGVuZ3RoLCAmZC0+a2V5LCAKCQkJICAgKHN0cnVjdCBzb2NrYWRkcl9pbiAqKUxPQ0FMX0FERFIsCgkJCSAgIChzdHJ1Y3Qgc29ja2FkZHJfaW4gKilSRU1PVEVfQUREUik7CiAgICBlbHNlIGlmKGxldmVsID09IHByb3RfcHJpdmF0ZSkKCXJldHVybiBrcmJfbWtfcHJpdihmcm9tLCAqdG8sIGxlbmd0aCwgZC0+c2NoZWR1bGUsICZkLT5rZXksIAoJCQkgICAoc3RydWN0IHNvY2thZGRyX2luICopTE9DQUxfQUREUiwKCQkJICAgKHN0cnVjdCBzb2NrYWRkcl9pbiAqKVJFTU9URV9BRERSKTsKICAgIGVsc2UKCXJldHVybiAtMTsKfQoKI2lmZGVmIEZUUF9TRVJWRVIKCnN0YXRpYyBpbnQKa3JiNF9hZGF0KHZvaWQgKmFwcF9kYXRhLCB2b2lkICpidWYsIHNpemVfdCBsZW4pCnsKICAgIEtURVhUX1NUIHRrdDsKICAgIEFVVEhfREFUIGF1dGhfZGF0OwogICAgY2hhciAqcDsKICAgIGludCBrZXJyb3I7CiAgICB1X2ludDMyX3QgY3M7CiAgICBjaGFyIG1zZ1szNV07IC8qIHNpemUgb2YgZW5jcnlwdGVkIGJsb2NrICovCiAgICBpbnQgdG1wX2xlbjsKICAgIHN0cnVjdCBrcmI0X2RhdGEgKmQgPSBhcHBfZGF0YTsKICAgIGNoYXIgaW5zdFtJTlNUX1NaXTsKICAgIHN0cnVjdCBzb2NrYWRkcl9pbiAqaGlzX2FkZHJfc2luID0gKHN0cnVjdCBzb2NrYWRkcl9pbiAqKWhpc19hZGRyOwoKICAgIG1lbWNweSh0a3QuZGF0LCBidWYsIGxlbik7CiAgICB0a3QubGVuZ3RoID0gbGVuOwoKICAgIGtfZ2V0c29ja2luc3QoMCwgaW5zdCwgc2l6ZW9mKGluc3QpKTsKICAgIGtlcnJvciA9IGtyYl9yZF9yZXEoJnRrdCwgImZ0cCIsIGluc3QsIAoJCQloaXNfYWRkcl9zaW4tPnNpbl9hZGRyLnNfYWRkciwgJmF1dGhfZGF0LCAiIik7CiAgICBpZihrZXJyb3IgPT0gUkRfQVBfVU5ERUMpewoJa19nZXRzb2NraW5zdCgwLCBpbnN0LCBzaXplb2YoaW5zdCkpOwoJa2Vycm9yID0ga3JiX3JkX3JlcSgmdGt0LCAicmNtZCIsIGluc3QsIAoJCQkgICAgaGlzX2FkZHJfc2luLT5zaW5fYWRkci5zX2FkZHIsICZhdXRoX2RhdCwgIiIpOwogICAgfQoKICAgIGlmKGtlcnJvcil7CglyZXBseSg1MzUsICJFcnJvciByZWFkaW5nIHJlcXVlc3Q6ICVzLiIsIGtyYl9nZXRfZXJyX3RleHQoa2Vycm9yKSk7CglyZXR1cm4gLTE7CiAgICB9CiAgICAKICAgIG1lbWNweShkLT5rZXksIGF1dGhfZGF0LnNlc3Npb24sIHNpemVvZihkLT5rZXkpKTsKICAgIGRlc19zZXRfa2V5KCZkLT5rZXksIGQtPnNjaGVkdWxlKTsKCiAgICBzdHJsY3B5KGQtPm5hbWUsIGF1dGhfZGF0LnBuYW1lLCBzaXplb2YoZC0+bmFtZSkpOwogICAgc3RybGNweShkLT5pbnN0YW5jZSwgYXV0aF9kYXQucGluc3QsIHNpemVvZihkLT5pbnN0YW5jZSkpOwogICAgc3RybGNweShkLT5yZWFsbSwgYXV0aF9kYXQucHJlYWxtLCBzaXplb2YoZC0+aW5zdGFuY2UpKTsKCiAgICBjcyA9IGF1dGhfZGF0LmNoZWNrc3VtICsgMTsKICAgIHsKCXVuc2lnbmVkIGNoYXIgdG1wWzRdOwoJS1JCX1BVVF9JTlQoY3MsIHRtcCwgNCwgc2l6ZW9mKHRtcCkpOwoJdG1wX2xlbiA9IGtyYl9ta19zYWZlKHRtcCwgbXNnLCA0LCAmZC0+a2V5LAoJCQkgICAgICAoc3RydWN0IHNvY2thZGRyX2luICopTE9DQUxfQUREUiwKCQkJICAgICAgKHN0cnVjdCBzb2NrYWRkcl9pbiAqKVJFTU9URV9BRERSKTsKICAgIH0KICAgIGlmKHRtcF9sZW4gPCAwKXsKCXJlcGx5KDUzNSwgIkVycm9yIGNyZWF0aW5nIHJlcGx5OiAlcy4iLCBzdHJlcnJvcihlcnJubykpOwoJcmV0dXJuIC0xOwogICAgfQogICAgbGVuID0gdG1wX2xlbjsKICAgIGlmKGJhc2U2NF9lbmNvZGUobXNnLCBsZW4sICZwKSA8IDApIHsKCXJlcGx5KDUzNSwgIk91dCBvZiBtZW1vcnkgYmFzZTY0LWVuY29kaW5nLiIpOwoJcmV0dXJuIC0xOwogICAgfQogICAgcmVwbHkoMjM1LCAiQURBVD0lcyIsIHApOwogICAgc2VjX2NvbXBsZXRlID0gMTsKICAgIGZyZWUocCk7CiAgICByZXR1cm4gMDsKfQoKc3RhdGljIGludAprcmI0X3VzZXJvayh2b2lkICphcHBfZGF0YSwgY2hhciAqdXNlcikKewogICAgc3RydWN0IGtyYjRfZGF0YSAqZCA9IGFwcF9kYXRhOwogICAgcmV0dXJuIGtyYl9rdXNlcm9rKGQtPm5hbWUsIGQtPmluc3RhbmNlLCBkLT5yZWFsbSwgdXNlcik7Cn0KCnN0cnVjdCBzZWNfc2VydmVyX21lY2gga3JiNF9zZXJ2ZXJfbWVjaCA9IHsKICAgICJLRVJCRVJPU19WNCIsCiAgICBzaXplb2Yoc3RydWN0IGtyYjRfZGF0YSksCiAgICBOVUxMLCAvKiBpbml0ICovCiAgICBOVUxMLCAvKiBlbmQgKi8KICAgIGtyYjRfY2hlY2tfcHJvdCwKICAgIGtyYjRfb3ZlcmhlYWQsCiAgICBrcmI0X2VuY29kZSwKICAgIGtyYjRfZGVjb2RlLAogICAgLyogKi8KICAgIE5VTEwsCiAgICBrcmI0X2FkYXQsCiAgICBOVUxMLCAvKiBwYnN6ICovCiAgICBOVUxMLCAvKiBjY2MgKi8KICAgIGtyYjRfdXNlcm9rCn07CgojZWxzZSAvKiBGVFBfU0VSVkVSICovCgpzdGF0aWMgaW50Cm1rX2F1dGgoc3RydWN0IGtyYjRfZGF0YSAqZCwgS1RFWFQgYWRhdCwgCgljaGFyICpzZXJ2aWNlLCBjaGFyICpob3N0LCBpbnQgY2hlY2tzdW0pCnsKICAgIGludCByZXQ7CiAgICBDUkVERU5USUFMUyBjcmVkOwogICAgY2hhciBzbmFtZVtTTkFNRV9TWl0sIGluc3RbSU5TVF9TWl0sIHJlYWxtW1JFQUxNX1NaXTsKCiAgICBzdHJsY3B5KHNuYW1lLCBzZXJ2aWNlLCBzaXplb2Yoc25hbWUpKTsKICAgIHN0cmxjcHkoaW5zdCwga3JiX2dldF9waG9zdChob3N0KSwgc2l6ZW9mKGluc3QpKTsKICAgIHN0cmxjcHkocmVhbG0sIGtyYl9yZWFsbW9maG9zdChob3N0KSwgc2l6ZW9mKHJlYWxtKSk7CiAgICByZXQgPSBrcmJfbWtfcmVxKGFkYXQsIHNuYW1lLCBpbnN0LCByZWFsbSwgY2hlY2tzdW0pOwogICAgaWYocmV0KQoJcmV0dXJuIHJldDsKICAgIHN0cmxjcHkoc25hbWUsIHNlcnZpY2UsIHNpemVvZihzbmFtZSkpOwogICAgc3RybGNweShpbnN0LCBrcmJfZ2V0X3Bob3N0KGhvc3QpLCBzaXplb2YoaW5zdCkpOwogICAgc3RybGNweShyZWFsbSwga3JiX3JlYWxtb2Zob3N0KGhvc3QpLCBzaXplb2YocmVhbG0pKTsKICAgIHJldCA9IGtyYl9nZXRfY3JlZChzbmFtZSwgaW5zdCwgcmVhbG0sICZjcmVkKTsKICAgIG1lbW1vdmUoJmQtPmtleSwgJmNyZWQuc2Vzc2lvbiwgc2l6ZW9mKGRlc19jYmxvY2spKTsKICAgIGRlc19rZXlfc2NoZWQoJmQtPmtleSwgZC0+c2NoZWR1bGUpOwogICAgbWVtc2V0KCZjcmVkLCAwLCBzaXplb2YoY3JlZCkpOwogICAgcmV0dXJuIHJldDsKfQoKc3RhdGljIGludAprcmI0X2F1dGgodm9pZCAqYXBwX2RhdGEsIHN0cnVjdCBjb25uZWN0ZGF0YSAqY29ubikKewogICAgaW50IHJldDsKICAgIGNoYXIgKnA7CiAgICBpbnQgbGVuOwogICAgS1RFWFRfU1QgYWRhdDsKICAgIE1TR19EQVQgbXNnX2RhdGE7CiAgICBpbnQgY2hlY2tzdW07CiAgICB1X2ludDMyX3QgY3M7CiAgICBzdHJ1Y3Qga3JiNF9kYXRhICpkID0gYXBwX2RhdGE7CiAgICBzdHJ1Y3Qgc29ja2FkZHJfaW4gKmxvY2FsYWRkciAgPSAoc3RydWN0IHNvY2thZGRyX2luICopTE9DQUxfQUREUjsKI2lmIDAKICAgIHN0cnVjdCBzb2NrYWRkcl9pbiAqcmVtb3RlYWRkciA9IChzdHJ1Y3Qgc29ja2FkZHJfaW4gKilSRU1PVEVfQUREUjsKI2VuZGlmCiAgICBjaGFyICpob3N0ID0gY29ubi0+aHAtPmhfbmFtZTsKICAgIHNpemVfdCBucmVhZDsKICAgIGludCBsID0gc2l6ZW9mKGxvY2FsX2FkZHIpOwoKICAgIGlmKGdldHNvY2tuYW1lKGNvbm4tPmRhdGEtPmZpcnN0c29ja2V0LAogICAgICAgICAgICAgICAgICAgKHN0cnVjdCBzb2NrYWRkciAqKUxPQ0FMX0FERFIsICZsKSA8IDApCglwZXJyb3IoImdldHNvY2tuYW1lKCkiKTsKCiAgICBjaGVja3N1bSA9IGdldHBpZCgpOwogICAgcmV0ID0gbWtfYXV0aChkLCAmYWRhdCwgImZ0cCIsIGhvc3QsIGNoZWNrc3VtKTsKICAgIGlmKHJldCA9PSBLRENfUFJfVU5LTk9XTikKCXJldCA9IG1rX2F1dGgoZCwgJmFkYXQsICJyY21kIiwgaG9zdCwgY2hlY2tzdW0pOwogICAgaWYocmV0KXsKCXByaW50ZigiJXNcbiIsIGtyYl9nZXRfZXJyX3RleHQocmV0KSk7CglyZXR1cm4gQVVUSF9DT05USU5VRTsKICAgIH0KCiNpZmRlZiBIQVZFX0tSQl9HRVRfT1VSX0lQX0ZPUl9SRUFMTQogICAgaWYgKGtyYl9nZXRfY29uZmlnX2Jvb2woIm5hdF9pbl91c2UiKSkgewogICAgICBzdHJ1Y3QgaW5fYWRkciBuYXRBZGRyOwoKICAgICAgaWYgKGtyYl9nZXRfb3VyX2lwX2Zvcl9yZWFsbShrcmJfcmVhbG1vZmhvc3QoaG9zdCksCgkJCQkgICAmbmF0QWRkcikgIT0gS1NVQ0NFU1MKCSAgJiYga3JiX2dldF9vdXJfaXBfZm9yX3JlYWxtKE5VTEwsICZuYXRBZGRyKSAhPSBLU1VDQ0VTUykKCXByaW50ZigiQ2FuJ3QgZ2V0IGFkZHJlc3MgZm9yIHJlYWxtICVzXG4iLAoJICAgICAgIGtyYl9yZWFsbW9maG9zdChob3N0KSk7CiAgICAgIGVsc2UgewoJaWYgKG5hdEFkZHIuc19hZGRyICE9IGxvY2FsYWRkci0+c2luX2FkZHIuc19hZGRyKSB7CgkgIHByaW50ZigiVXNpbmcgTkFUIElQIGFkZHJlc3MgKCVzKSBmb3Iga2VyYmVyb3MgNFxuIiwKCQkgKGNoYXIgKilpbmV0X250b2EobmF0QWRkcikpOwoJICBsb2NhbGFkZHItPnNpbl9hZGRyID0gbmF0QWRkcjsKCSAgCgkgIC8qCgkgICAqIFRoaXMgbm90IHRoZSBiZXN0IHBsYWNlIHRvIGRvIHRoaXMsIGJ1dCBpdAoJICAgKiBpcyBoZXJlIHdlIGtub3cgdGhhdCAocHJvYmFibHkpIE5BVCBpcyBpbgoJICAgKiB1c2UhCgkgICAqLwoKCSAgLypwYXNzaXZlbW9kZSA9IDE7KioqLwoJICAvKnByaW50ZigiU2V0dGluZzogUGFzc2l2ZSBtb2RlIG9uLlxuIik7KioqLwoJfQogICAgICB9CiAgICB9CiNlbmRpZgoKICAgIC8qcHJpbnRmKCJMb2NhbCBhZGRyZXNzIGlzICVzXG4iLCBpbmV0X250b2EobG9jYWxhZGRyLT5zaW5fYWRkcikpOyoqKi8KICAgIC8qcHJpbnRmKCJSZW1vdGUgYWRkcmVzcyBpcyAlc1xuIiwgaW5ldF9udG9hKHJlbW90ZWFkZHItPnNpbl9hZGRyKSk7KioqLwoKICAgIGlmKEN1cmxfYmFzZTY0X2VuY29kZShhZGF0LmRhdCwgYWRhdC5sZW5ndGgsICZwKSA8IDApIHsKCXByaW50ZigiT3V0IG9mIG1lbW9yeSBiYXNlNjQtZW5jb2RpbmcuXG4iKTsKCXJldHVybiBBVVRIX0NPTlRJTlVFOwogICAgfQogICAgLypyZXQgPSBjb21tYW5kKCJBREFUICVzIiwgcCkqLwogICAgQ3VybF9mdHBzZW5kZihjb25uLT5kYXRhLT5maXJzdHNvY2tldCwgY29ubiwgIkFEQVQgJXMiLCBwKTsKICAgIC8qIHdhaXQgZm9yIGZlZWRiYWNrICovCiAgICBucmVhZCA9IEN1cmxfR2V0RlRQUmVzcG9uc2UoY29ubi0+ZGF0YS0+Zmlyc3Rzb2NrZXQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29ubi0+ZGF0YS0+YnVmZmVyLCBjb25uLCBOVUxMKTsKICAgIGlmKG5yZWFkIDwgMCkKCXJldHVybiAvKkNVUkxFX09QRVJBVElPTl9USU1FT1VURUQqLy0xOwogICAgZnJlZShwKTsKCiAgICBpZigvKnJldCAhPSBDT01QTEVURSovY29ubi0+ZGF0YS0+YnVmZmVyWzBdICE9ICcyJyl7CglwcmludGYoIlNlcnZlciBkaWRuJ3QgYWNjZXB0IGF1dGggZGF0YS5cbiIpOwoJcmV0dXJuIEFVVEhfRVJST1I7CiAgICB9CgogICAgcCA9IHN0cnN0cigvKnJlcGx5X3N0cmluZyovY29ubi0+ZGF0YS0+YnVmZmVyLCAiQURBVD0iKTsKICAgIGlmKCFwKXsKCXByaW50ZigiUmVtb3RlIGhvc3QgZGlkbid0IHNlbmQgYWRhdCByZXBseS5cbiIpOwoJcmV0dXJuIEFVVEhfRVJST1I7CiAgICB9CiAgICBwICs9IDU7CiAgICBsZW4gPSBDdXJsX2Jhc2U2NF9kZWNvZGUocCwgYWRhdC5kYXQpOwogICAgaWYobGVuIDwgMCl7CglwcmludGYoIkZhaWxlZCB0byBkZWNvZGUgYmFzZTY0IGZyb20gc2VydmVyLlxuIik7CglyZXR1cm4gQVVUSF9FUlJPUjsKICAgIH0KICAgIGFkYXQubGVuZ3RoID0gbGVuOwogICAgcmV0ID0ga3JiX3JkX3NhZmUoYWRhdC5kYXQsIGFkYXQubGVuZ3RoLCAmZC0+a2V5LCAKCQkgICAgICAoc3RydWN0IHNvY2thZGRyX2luICopaGlzY3RsYWRkciwgCgkJICAgICAgKHN0cnVjdCBzb2NrYWRkcl9pbiAqKW15Y3RsYWRkciwgJm1zZ19kYXRhKTsKICAgIGlmKHJldCl7CglwcmludGYoIkVycm9yIHJlYWRpbmcgcmVwbHkgZnJvbSBzZXJ2ZXI6ICVzLlxuIiwgCgkgICAgICAga3JiX2dldF9lcnJfdGV4dChyZXQpKTsKCXJldHVybiBBVVRIX0VSUk9SOwogICAgfQogICAga3JiX2dldF9pbnQobXNnX2RhdGEuYXBwX2RhdGEsICZjcywgNCwgMCk7CiAgICBpZihjcyAtIGNoZWNrc3VtICE9IDEpewoJcHJpbnRmKCJCYWQgY2hlY2tzdW0gcmV0dXJuZWQgZnJvbSBzZXJ2ZXIuXG4iKTsKCXJldHVybiBBVVRIX0VSUk9SOwogICAgfQogICAgcmV0dXJuIEFVVEhfT0s7Cn0KCnN0cnVjdCBzZWNfY2xpZW50X21lY2gga3JiNF9jbGllbnRfbWVjaCA9IHsKICAgICJLRVJCRVJPU19WNCIsCiAgICBzaXplb2Yoc3RydWN0IGtyYjRfZGF0YSksCiAgICBOVUxMLCAvKiBpbml0ICovCiAgICBrcmI0X2F1dGgsCiAgICBOVUxMLCAvKiBlbmQgKi8KICAgIGtyYjRfY2hlY2tfcHJvdCwKICAgIGtyYjRfb3ZlcmhlYWQsCiAgICBrcmI0X2VuY29kZSwKICAgIGtyYjRfZGVjb2RlCn07CgojZW5kaWYgLyogRlRQX1NFUlZFUiAqLwoKdm9pZCBrcmJfa2F1dGgoc3RydWN0IGNvbm5lY3RkYXRhICpjb25uKQp7CiAgICBkZXNfY2Jsb2NrIGtleTsKICAgIGRlc19rZXlfc2NoZWR1bGUgc2NoZWR1bGU7CiAgICBLVEVYVF9TVCB0a3QsIHRrdGNvcHk7CiAgICBjaGFyICpuYW1lOwogICAgY2hhciAqcDsKICAgIGNoYXIgcGFzc3dkWzEwMF07CiAgICBpbnQgdG1wOwogICAgc2l6ZV90IG5yZWFkOwoJCiAgICBpbnQgc2F2ZTsKCiAgICBzYXZlID0gc2V0X2NvbW1hbmRfcHJvdChjb25uLCBwcm90X3ByaXZhdGUpOwogICAgLypyZXQgPSBjb21tYW5kKCJTSVRFIEtBVVRIICVzIiwgbmFtZSk7KioqLwogICAgQ3VybF9mdHBzZW5kZihjb25uLT5kYXRhLT5maXJzdHNvY2tldCwgY29ubiwKICAgICAgICAgICAgICJTSVRFIEtBVVRIICVzIiwgY29ubi0+ZGF0YS0+dXNlcik7CiAgICAvKiB3YWl0IGZvciBmZWVkYmFjayAqLwogICAgbnJlYWQgPSBDdXJsX0dldEZUUFJlc3BvbnNlKGNvbm4tPmRhdGEtPmZpcnN0c29ja2V0LCBjb25uLT5kYXRhLT5idWZmZXIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29ubiwgTlVMTCk7CiAgICBpZihucmVhZCA8IDApCglyZXR1cm4gLypDVVJMRV9PUEVSQVRJT05fVElNRU9VVEVEKi87CgogICAgaWYoLypyZXQgIT0gQ09OVElOVUUqL2Nvbm4tPmRhdGEtPmJ1ZmZlclswXSAhPSAnMycpewoJc2V0X2NvbW1hbmRfcHJvdChjb25uLCBzYXZlKTsKCS8qY29kZSA9IC0xOyoqKi8KCXJldHVybjsKICAgIH0KICAgIHAgPSBzdHJzdHIoLypyZXBseV9zdHJpbmcqKiovY29ubi0+ZGF0YS0+YnVmZmVyLCAiVD0iKTsKICAgIGlmKCFwKXsKCXByaW50ZigiQmFkIHJlcGx5IGZyb20gc2VydmVyLlxuIik7CglzZXRfY29tbWFuZF9wcm90KGNvbm4sIHNhdmUpOwoJLypjb2RlID0gLTE7KioqLwoJcmV0dXJuOwogICAgfQogICAgcCArPSAyOwogICAgdG1wID0gQ3VybF9iYXNlNjRfZGVjb2RlKHAsICZ0a3QuZGF0KTsKICAgIGlmKHRtcCA8IDApewoJcHJpbnRmKCJGYWlsZWQgdG8gZGVjb2RlIGJhc2U2NCBpbiByZXBseS5cbiIpOwoJc2V0X2NvbW1hbmRfcHJvdChjb25uLCBzYXZlKTsKCS8qY29kZSA9IC0xOyoqKi8KCXJldHVybjsKICAgIH0KICAgIHRrdC5sZW5ndGggPSB0bXA7CiAgICB0a3Rjb3B5Lmxlbmd0aCA9IHRrdC5sZW5ndGg7CiAgICAKICAgIHAgPSBzdHJzdHIoLypyZXBseV9zdHJpbmcqKiovY29ubi0+ZGF0YS0+YnVmZmVyLCAiUD0iKTsKICAgIGlmKCFwKXsKCXByaW50ZigiQmFkIHJlcGx5IGZyb20gc2VydmVyLlxuIik7CglzZXRfY29tbWFuZF9wcm90KGNvbm4sIHNhdmUpOwoJLypjb2RlID0gLTE7KioqLwoJcmV0dXJuOwogICAgfQogICAgbmFtZSA9IHAgKyAyOwogICAgZm9yKDsgKnAgJiYgKnAgIT0gJyAnICYmICpwICE9ICdccicgJiYgKnAgIT0gJ1xuJzsgcCsrKTsKICAgICpwID0gMDsKCiNpZiAwCiAgICBzbnByaW50ZihidWYsIHNpemVvZihidWYpLCAiUGFzc3dvcmQgZm9yICVzOiIsIG5hbWUpOwogICAgaWYgKGRlc19yZWFkX3B3X3N0cmluZyAocGFzc3dkLCBzaXplb2YocGFzc3dkKS0xLCBidWYsIDApKQogICAgICAgICpwYXNzd2QgPSAnXDAnOwogICAgZGVzX3N0cmluZ190b19rZXkgKHBhc3N3ZCwgJmtleSk7CiNlbHNlCiAgICBkZXNfc3RyaW5nX3RvX2tleSAoY29ubi0+ZGF0YS0+cGFzc3dkLCAma2V5KTsKI2VuZGlmCgogICAgZGVzX2tleV9zY2hlZCgma2V5LCBzY2hlZHVsZSk7CiAgICAKICAgIGRlc19wY2JjX2VuY3J5cHQoKGRlc19jYmxvY2sqKXRrdC5kYXQsIChkZXNfY2Jsb2NrKil0a3Rjb3B5LmRhdCwKCQkgICAgIHRrdC5sZW5ndGgsCgkJICAgICBzY2hlZHVsZSwgJmtleSwgREVTX0RFQ1JZUFQpOwogICAgaWYgKHN0cmNtcCAoKGNoYXIqKXRrdGNvcHkuZGF0ICsgOCwKCQlLUkJfVElDS0VUX0dSQU5USU5HX1RJQ0tFVCkgIT0gMCkgewogICAgICAgIGFmc19zdHJpbmdfdG9fa2V5IChwYXNzd2QsCgkJCSAgIGtyYl9yZWFsbW9maG9zdCgvKmhvc3RuYW1lKioqL2Nvbm4tPmhwLT5oX25hbWUpLAoJCQkgICAma2V5KTsKCWRlc19rZXlfc2NoZWQgKCZrZXksIHNjaGVkdWxlKTsKCWRlc19wY2JjX2VuY3J5cHQoKGRlc19jYmxvY2sqKXRrdC5kYXQsIChkZXNfY2Jsb2NrKil0a3Rjb3B5LmRhdCwKCQkJIHRrdC5sZW5ndGgsCgkJCSBzY2hlZHVsZSwgJmtleSwgREVTX0RFQ1JZUFQpOwogICAgfQogICAgbWVtc2V0KGtleSwgMCwgc2l6ZW9mKGtleSkpOwogICAgbWVtc2V0KHNjaGVkdWxlLCAwLCBzaXplb2Yoc2NoZWR1bGUpKTsKICAgIG1lbXNldChwYXNzd2QsIDAsIHNpemVvZihwYXNzd2QpKTsKICAgIGlmKEN1cmxfYmFzZTY0X2VuY29kZSh0a3Rjb3B5LmRhdCwgdGt0Y29weS5sZW5ndGgsICZwKSA8IDApIHsKICAgICAgZmFpbGYoY29ubi0+ZGF0YSwgIk91dCBvZiBtZW1vcnkgYmFzZTY0LWVuY29kaW5nLlxuIik7CiAgICAgIHNldF9jb21tYW5kX3Byb3QoY29ubiwgc2F2ZSk7CiAgICAgIC8qY29kZSA9IC0xOyoqKi8KICAgICAgcmV0dXJuOwogICAgfQogICAgbWVtc2V0ICh0a3Rjb3B5LmRhdCwgMCwgdGt0Y29weS5sZW5ndGgpOwogICAgLypyZXQgPSBjb21tYW5kKCJTSVRFIEtBVVRIICVzICVzIiwgbmFtZSwgcCk7KioqLwogICAgQ3VybF9mdHBzZW5kZihjb25uLT5kYXRhLT5maXJzdHNvY2tldCwgY29ubiwKICAgICAgICAgICAgICJTSVRFIEtBVVRIICVzICVzIiwgbmFtZSwgcCk7CiAgICAvKiB3YWl0IGZvciBmZWVkYmFjayAqLwogICAgbnJlYWQgPSBDdXJsX0dldEZUUFJlc3BvbnNlKGNvbm4tPmRhdGEtPmZpcnN0c29ja2V0LCBjb25uLT5kYXRhLT5idWZmZXIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29ubiwgTlVMTCk7CiAgICBpZihucmVhZCA8IDApCglyZXR1cm4gLypDVVJMRV9PUEVSQVRJT05fVElNRU9VVEVEKi87CiAgICBmcmVlKHApOwogICAgc2V0X2NvbW1hbmRfcHJvdChjb25uLCBzYXZlKTsKfQoKI2VuZGlmIC8qIEtSQjQgKi8K