LyogVGhpcyBzb3VyY2UgY29kZSB3YXMgbW9kaWZpZWQgYnkgTWFydGluIEhlZGVuZmFsayA8bWhlQHN0YWNrZW4ua3RoLnNlPiBmb3IKICogdXNlIGluIEN1cmwuIE1hcnRpbidzIGxhdGVzdCBjaGFuZ2VzIHdlcmUgZG9uZSAyMDAwLTA5LTE4LgogKgogKiBJdCBoYXMgc2luY2UgYmVlbiBwYXRjaGVkIGF3YXkgbGlrZSBhIG1hZG1hbiBieSBEYW5pZWwgU3RlbmJlcmcgdG8gbWFrZSBpdAogKiBiZXR0ZXIgYXBwbGllZCB0byBjdXJsIGNvbmRpdGlvbnMsIGFuZCB0byBtYWtlIGl0IG5vdCB1c2UgZ2xvYmFscywgcG9sbHV0ZQogKiBuYW1lIHNwYWNlIGFuZCBtb3JlLgogKgogKiBDb3B5cmlnaHQgKGMpIDE5OTUsIDE5OTYsIDE5OTcsIDE5OTgsIDE5OTkgS3VuZ2xpZ2EgVGVrbmlza2EgSPZnc2tvbGFuCiAqIChSb3lhbCBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgU3RvY2tob2xtLCBTd2VkZW4pLgogKiBDb3B5cmlnaHQgKGMpIDIwMDQgLSAyMDA3IERhbmllbCBTdGVuYmVyZwogKiBBbGwgcmlnaHRzIHJlc2VydmVkLgogKgogKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCiAqIGFyZSBtZXQ6CiAqCiAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CiAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KICoKICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluIHRoZQogKiAgICBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUgZGlzdHJpYnV0aW9uLgogKgogKiAzLiBOZWl0aGVyIHRoZSBuYW1lIG9mIHRoZSBJbnN0aXR1dGUgbm9yIHRoZSBuYW1lcyBvZiBpdHMgY29udHJpYnV0b3JzCiAqICAgIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZQogKiAgICB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KICoKICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgSU5TVElUVVRFIEFORCBDT05UUklCVVRPUlMgYGBBUyBJUycnIEFORAogKiBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUKICogSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UKICogQVJFIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgSU5TVElUVVRFIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUKICogRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwKICogREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMKICogT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pCiAqIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUCiAqIExJQUJJTElUWSwgT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkKICogT1VUIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgogKiBTVUNIIERBTUFHRS4KICoKICogJElkJAogKi8KCiNpbmNsdWRlICJzZXR1cC5oIgoKI2lmbmRlZiBDVVJMX0RJU0FCTEVfRlRQCiNpZmRlZiBIQVZFX0tSQjQKCiNpbmNsdWRlIDxzdGRsaWIuaD4KI2lmZGVmIEhBVkVfTkVUREJfSAojaW5jbHVkZSA8bmV0ZGIuaD4KI2VuZGlmCiNpbmNsdWRlIDxzdHJpbmcuaD4KI2luY2x1ZGUgPGtyYi5oPgojaW5jbHVkZSA8ZGVzLmg+CgojaWZkZWYgSEFWRV9VTklTVERfSAojaW5jbHVkZSA8dW5pc3RkLmg+IC8qIGZvciBnZXRwaWQoKSAqLwojZW5kaWYKCiNpbmNsdWRlICJ1cmxkYXRhLmgiCiNpbmNsdWRlICJiYXNlNjQuaCIKI2luY2x1ZGUgImZ0cC5oIgojaW5jbHVkZSAic2VuZGYuaCIKI2luY2x1ZGUgImtyYjQuaCIKI2luY2x1ZGUgIm1lbW9yeS5oIgoKI2lmIGRlZmluZWQoSEFWRV9JTkVUX05UT0FfUikgJiYgIWRlZmluZWQoSEFWRV9JTkVUX05UT0FfUl9ERUNMKQojaW5jbHVkZSAiaW5ldF9udG9hX3IuaCIKI2VuZGlmCgovKiBUaGUgbGFzdCAjaW5jbHVkZSBmaWxlIHNob3VsZCBiZTogKi8KI2luY2x1ZGUgIm1lbWRlYnVnLmgiCgojZGVmaW5lIExPQ0FMX0FERFIgKCZjb25uLT5sb2NhbF9hZGRyKQojZGVmaW5lIFJFTU9URV9BRERSIGNvbm4tPmlwX2FkZHItPmFpX2FkZHIKI2RlZmluZSBteWN0bGFkZHIgTE9DQUxfQUREUgojZGVmaW5lIGhpc2N0bGFkZHIgUkVNT1RFX0FERFIKCnN0cnVjdCBrcmI0X2RhdGEgewogIGRlc19jYmxvY2sga2V5OwogIGRlc19rZXlfc2NoZWR1bGUgc2NoZWR1bGU7CiAgY2hhciBuYW1lW0FOQU1FX1NaXTsKICBjaGFyIGluc3RhbmNlW0lOU1RfU1pdOwogIGNoYXIgcmVhbG1bUkVBTE1fU1pdOwp9OwoKI2lmbmRlZiBIQVZFX1NUUkxDUFkKLyogaWYgaXQgZXZlciBnb2VzIG5vbi1zdGF0aWMsIG1ha2UgaXQgQ3VybF8gcHJlZml4ZWQhICovCnN0YXRpYyBzaXplX3QKc3RybGNweSAoY2hhciAqZHN0LCBjb25zdCBjaGFyICpzcmMsIHNpemVfdCBkc3Rfc3opCnsKICBzaXplX3QgbjsKICBjaGFyICpwOwoKICBmb3IgKHAgPSBkc3QsIG4gPSAwOwogICAgICAgbiArIDEgPCBkc3Rfc3ogJiYgKnNyYyAhPSAnXDAnOwogICAgICAgKytwLCArK3NyYywgKytuKQogICAgKnAgPSAqc3JjOwogICpwID0gJ1wwJzsKICBpZiAoKnNyYyA9PSAnXDAnKQogICAgcmV0dXJuIG47CiAgZWxzZQogICAgcmV0dXJuIG4gKyBzdHJsZW4gKHNyYyk7Cn0KI2Vsc2UKc2l6ZV90IHN0cmxjcHkgKGNoYXIgKmRzdCwgY29uc3QgY2hhciAqc3JjLCBzaXplX3QgZHN0X3N6KTsKI2VuZGlmCgpzdGF0aWMgaW50CmtyYjRfY2hlY2tfcHJvdCh2b2lkICphcHBfZGF0YSwgaW50IGxldmVsKQp7CiAgYXBwX2RhdGEgPSBOVUxMOyAvKiBwcmV2ZW50IGNvbXBpbGVyIHdhcm5pbmcgKi8KICBpZihsZXZlbCA9PSBwcm90X2NvbmZpZGVudGlhbCkKICAgIHJldHVybiAtMTsKICByZXR1cm4gMDsKfQoKc3RhdGljIGludAprcmI0X2RlY29kZSh2b2lkICphcHBfZGF0YSwgdm9pZCAqYnVmLCBpbnQgbGVuLCBpbnQgbGV2ZWwsCiAgICAgICAgICAgIHN0cnVjdCBjb25uZWN0ZGF0YSAqY29ubikKewogIE1TR19EQVQgbTsKICBpbnQgZTsKICBzdHJ1Y3Qga3JiNF9kYXRhICpkID0gYXBwX2RhdGE7CgogIGlmKGxldmVsID09IHByb3Rfc2FmZSkKICAgIGUgPSBrcmJfcmRfc2FmZShidWYsIGxlbiwgJmQtPmtleSwKICAgICAgICAgICAgICAgICAgICAoc3RydWN0IHNvY2thZGRyX2luICopUkVNT1RFX0FERFIsCiAgICAgICAgICAgICAgICAgICAgKHN0cnVjdCBzb2NrYWRkcl9pbiAqKUxPQ0FMX0FERFIsICZtKTsKICBlbHNlCiAgICBlID0ga3JiX3JkX3ByaXYoYnVmLCBsZW4sIGQtPnNjaGVkdWxlLCAmZC0+a2V5LAogICAgICAgICAgICAgICAgICAgIChzdHJ1Y3Qgc29ja2FkZHJfaW4gKilSRU1PVEVfQUREUiwKICAgICAgICAgICAgICAgICAgICAoc3RydWN0IHNvY2thZGRyX2luICopTE9DQUxfQUREUiwgJm0pOwogIGlmKGUpIHsKICAgIHN0cnVjdCBTZXNzaW9uSGFuZGxlICpkYXRhID0gY29ubi0+ZGF0YTsKICAgIGluZm9mKGRhdGEsICJrcmI0X2RlY29kZTogJXNcbiIsIGtyYl9nZXRfZXJyX3RleHQoZSkpOwogICAgcmV0dXJuIC0xOwogIH0KICBtZW1tb3ZlKGJ1ZiwgbS5hcHBfZGF0YSwgbS5hcHBfbGVuZ3RoKTsKICByZXR1cm4gbS5hcHBfbGVuZ3RoOwp9CgpzdGF0aWMgaW50CmtyYjRfb3ZlcmhlYWQodm9pZCAqYXBwX2RhdGEsIGludCBsZXZlbCwgaW50IGxlbikKewogIC8qIG5vIGFyZ3VtZW50cyBhcmUgdXNlZCwganVzdCBpbml0IHRoZW0gdG8gcHJldmVudCBjb21waWxlciB3YXJuaW5ncyAqLwogIGFwcF9kYXRhID0gTlVMTDsKICBsZXZlbCA9IDA7CiAgbGVuID0gMDsKICByZXR1cm4gMzE7Cn0KCnN0YXRpYyBpbnQKa3JiNF9lbmNvZGUodm9pZCAqYXBwX2RhdGEsIHZvaWQgKmZyb20sIGludCBsZW5ndGgsIGludCBsZXZlbCwgdm9pZCAqKnRvLAogICAgICAgICAgICBzdHJ1Y3QgY29ubmVjdGRhdGEgKmNvbm4pCnsKICBzdHJ1Y3Qga3JiNF9kYXRhICpkID0gYXBwX2RhdGE7CiAgKnRvID0gbWFsbG9jKGxlbmd0aCArIDMxKTsKICBpZihsZXZlbCA9PSBwcm90X3NhZmUpCiAgICByZXR1cm4ga3JiX21rX3NhZmUoZnJvbSwgKnRvLCBsZW5ndGgsICZkLT5rZXksCiAgICAgICAgICAgICAgICAgICAgICAgKHN0cnVjdCBzb2NrYWRkcl9pbiAqKUxPQ0FMX0FERFIsCiAgICAgICAgICAgICAgICAgICAgICAgKHN0cnVjdCBzb2NrYWRkcl9pbiAqKVJFTU9URV9BRERSKTsKICBlbHNlIGlmKGxldmVsID09IHByb3RfcHJpdmF0ZSkKICAgIHJldHVybiBrcmJfbWtfcHJpdihmcm9tLCAqdG8sIGxlbmd0aCwgZC0+c2NoZWR1bGUsICZkLT5rZXksCiAgICAgICAgICAgICAgICAgICAgICAgKHN0cnVjdCBzb2NrYWRkcl9pbiAqKUxPQ0FMX0FERFIsCiAgICAgICAgICAgICAgICAgICAgICAgKHN0cnVjdCBzb2NrYWRkcl9pbiAqKVJFTU9URV9BRERSKTsKICBlbHNlCiAgICByZXR1cm4gLTE7Cn0KCnN0YXRpYyBpbnQKbWtfYXV0aChzdHJ1Y3Qga3JiNF9kYXRhICpkLCBLVEVYVCBhZGF0LAogICAgICAgIGNvbnN0IGNoYXIgKnNlcnZpY2UsIGNoYXIgKmhvc3QsIGludCBjaGVja3N1bSkKewogIGludCByZXQ7CiAgQ1JFREVOVElBTFMgY3JlZDsKICBjaGFyIHNuYW1lW1NOQU1FX1NaXSwgaW5zdFtJTlNUX1NaXSwgcmVhbG1bUkVBTE1fU1pdOwoKICBzdHJsY3B5KHNuYW1lLCBzZXJ2aWNlLCBzaXplb2Yoc25hbWUpKTsKICBzdHJsY3B5KGluc3QsIGtyYl9nZXRfcGhvc3QoaG9zdCksIHNpemVvZihpbnN0KSk7CiAgc3RybGNweShyZWFsbSwga3JiX3JlYWxtb2Zob3N0KGhvc3QpLCBzaXplb2YocmVhbG0pKTsKICByZXQgPSBrcmJfbWtfcmVxKGFkYXQsIHNuYW1lLCBpbnN0LCByZWFsbSwgY2hlY2tzdW0pOwogIGlmKHJldCkKICAgIHJldHVybiByZXQ7CiAgc3RybGNweShzbmFtZSwgc2VydmljZSwgc2l6ZW9mKHNuYW1lKSk7CiAgc3RybGNweShpbnN0LCBrcmJfZ2V0X3Bob3N0KGhvc3QpLCBzaXplb2YoaW5zdCkpOwogIHN0cmxjcHkocmVhbG0sIGtyYl9yZWFsbW9maG9zdChob3N0KSwgc2l6ZW9mKHJlYWxtKSk7CiAgcmV0ID0ga3JiX2dldF9jcmVkKHNuYW1lLCBpbnN0LCByZWFsbSwgJmNyZWQpOwogIG1lbW1vdmUoJmQtPmtleSwgJmNyZWQuc2Vzc2lvbiwgc2l6ZW9mKGRlc19jYmxvY2spKTsKICBkZXNfa2V5X3NjaGVkKCZkLT5rZXksIGQtPnNjaGVkdWxlKTsKICBtZW1zZXQoJmNyZWQsIDAsIHNpemVvZihjcmVkKSk7CiAgcmV0dXJuIHJldDsKfQoKI2lmZGVmIEhBVkVfS1JCX0dFVF9PVVJfSVBfRk9SX1JFQUxNCmludCBrcmJfZ2V0X291cl9pcF9mb3JfcmVhbG0oY2hhciAqLCBzdHJ1Y3QgaW5fYWRkciAqKTsKI2VuZGlmCgpzdGF0aWMgaW50CmtyYjRfYXV0aCh2b2lkICphcHBfZGF0YSwgc3RydWN0IGNvbm5lY3RkYXRhICpjb25uKQp7CiAgaW50IHJldDsKICBjaGFyICpwOwogIHVuc2lnbmVkIGNoYXIgKnB0cjsKICBzaXplX3QgbGVuOwogIEtURVhUX1NUIGFkYXQ7CiAgTVNHX0RBVCBtc2dfZGF0YTsKICBpbnQgY2hlY2tzdW07CiAgdV9pbnQzMl90IGNzOwogIHN0cnVjdCBrcmI0X2RhdGEgKmQgPSBhcHBfZGF0YTsKICBjaGFyICpob3N0ID0gY29ubi0+aG9zdC5uYW1lOwogIHNzaXplX3QgbnJlYWQ7CiAgaW50IGwgPSBzaXplb2YoY29ubi0+bG9jYWxfYWRkcik7CiAgc3RydWN0IFNlc3Npb25IYW5kbGUgKmRhdGEgPSBjb25uLT5kYXRhOwogIENVUkxjb2RlIHJlc3VsdDsKCiAgaWYoZ2V0c29ja25hbWUoY29ubi0+c29ja1tGSVJTVFNPQ0tFVF0sCiAgICAgICAgICAgICAgICAgKHN0cnVjdCBzb2NrYWRkciAqKUxPQ0FMX0FERFIsICZsKSA8IDApCiAgICBwZXJyb3IoImdldHNvY2tuYW1lKCkiKTsKCiAgY2hlY2tzdW0gPSBnZXRwaWQoKTsKICByZXQgPSBta19hdXRoKGQsICZhZGF0LCAiZnRwIiwgaG9zdCwgY2hlY2tzdW0pOwogIGlmKHJldCA9PSBLRENfUFJfVU5LTk9XTikKICAgIHJldCA9IG1rX2F1dGgoZCwgJmFkYXQsICJyY21kIiwgaG9zdCwgY2hlY2tzdW0pOwogIGlmKHJldCkgewogICAgaW5mb2YoZGF0YSwgIiVzXG4iLCBrcmJfZ2V0X2Vycl90ZXh0KHJldCkpOwogICAgcmV0dXJuIEFVVEhfQ09OVElOVUU7CiAgfQoKI2lmZGVmIEhBVkVfS1JCX0dFVF9PVVJfSVBfRk9SX1JFQUxNCiAgaWYgKGtyYl9nZXRfY29uZmlnX2Jvb2woIm5hdF9pbl91c2UiKSkgewogICAgc3RydWN0IHNvY2thZGRyX2luICpsb2NhbGFkZHIgID0gKHN0cnVjdCBzb2NrYWRkcl9pbiAqKUxPQ0FMX0FERFI7CiAgICBzdHJ1Y3QgaW5fYWRkciBuYXRBZGRyOwoKICAgIGlmIChrcmJfZ2V0X291cl9pcF9mb3JfcmVhbG0oa3JiX3JlYWxtb2Zob3N0KGhvc3QpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmbmF0QWRkcikgIT0gS1NVQ0NFU1MKICAgICAgICAmJiBrcmJfZ2V0X291cl9pcF9mb3JfcmVhbG0oTlVMTCwgJm5hdEFkZHIpICE9IEtTVUNDRVNTKQogICAgICBpbmZvZihkYXRhLCAiQ2FuJ3QgZ2V0IGFkZHJlc3MgZm9yIHJlYWxtICVzXG4iLAogICAgICAgICAgICAgICAgIGtyYl9yZWFsbW9maG9zdChob3N0KSk7CiAgICBlbHNlIHsKICAgICAgaWYgKG5hdEFkZHIuc19hZGRyICE9IGxvY2FsYWRkci0+c2luX2FkZHIuc19hZGRyKSB7CiNpZmRlZiBIQVZFX0lORVRfTlRPQV9SCiAgICAgICAgY2hhciBudG9hX2J1Zls2NF07CiAgICAgICAgY2hhciAqaXAgPSAoY2hhciAqKWluZXRfbnRvYV9yKG5hdEFkZHIsIG50b2FfYnVmLCBzaXplb2YobnRvYV9idWYpKTsKI2Vsc2UKICAgICAgICBjaGFyICppcCA9IChjaGFyICopaW5ldF9udG9hKG5hdEFkZHIpOwojZW5kaWYKICAgICAgICBpbmZvZihkYXRhLCAiVXNpbmcgTkFUIElQIGFkZHJlc3MgKCVzKSBmb3Iga2VyYmVyb3MgNFxuIiwgaXApOwogICAgICAgIGxvY2FsYWRkci0+c2luX2FkZHIgPSBuYXRBZGRyOwogICAgICB9CiAgICB9CiAgfQojZW5kaWYKCiAgaWYoQ3VybF9iYXNlNjRfZW5jb2RlKGNvbm4tPmRhdGEsIChjaGFyICopYWRhdC5kYXQsIGFkYXQubGVuZ3RoLCAmcCkgPCAxKSB7CiAgICBDdXJsX2ZhaWxmKGRhdGEsICJPdXQgb2YgbWVtb3J5IGJhc2U2NC1lbmNvZGluZyIpOwogICAgcmV0dXJuIEFVVEhfQ09OVElOVUU7CiAgfQoKICByZXN1bHQgPSBDdXJsX2Z0cHNlbmRmKGNvbm4sICJBREFUICVzIiwgcCk7CgogIGZyZWUocCk7CgogIGlmKHJlc3VsdCkKICAgIHJldHVybiAtMjsKCiAgaWYoQ3VybF9HZXRGVFBSZXNwb25zZSgmbnJlYWQsIGNvbm4sIE5VTEwpKQogICAgcmV0dXJuIC0xOwoKICBpZihkYXRhLT5zdGF0ZS5idWZmZXJbMF0gIT0gJzInKXsKICAgIEN1cmxfZmFpbGYoZGF0YSwgIlNlcnZlciBkaWRuJ3QgYWNjZXB0IGF1dGggZGF0YSIpOwogICAgcmV0dXJuIEFVVEhfRVJST1I7CiAgfQoKICBwID0gc3Ryc3RyKGRhdGEtPnN0YXRlLmJ1ZmZlciwgIkFEQVQ9Iik7CiAgaWYoIXApIHsKICAgIEN1cmxfZmFpbGYoZGF0YSwgIlJlbW90ZSBob3N0IGRpZG4ndCBzZW5kIGFkYXQgcmVwbHkiKTsKICAgIHJldHVybiBBVVRIX0VSUk9SOwogIH0KICBwICs9IDU7CiAgbGVuID0gQ3VybF9iYXNlNjRfZGVjb2RlKHAsICZwdHIpOwogIGlmKGxlbiA+IHNpemVvZihhZGF0LmRhdCktMSkgewogICAgZnJlZShwdHIpOwogICAgbGVuPTA7CiAgfQogIGlmKCFsZW4gfHwgIXB0cikgewogICAgQ3VybF9mYWlsZihkYXRhLCAiRmFpbGVkIHRvIGRlY29kZSBiYXNlNjQgZnJvbSBzZXJ2ZXIiKTsKICAgIHJldHVybiBBVVRIX0VSUk9SOwogIH0KICBtZW1jcHkoKGNoYXIgKilhZGF0LmRhdCwgcHRyLCBsZW4pOwogIGZyZWUocHRyKTsKICBhZGF0Lmxlbmd0aCA9IGxlbjsKICByZXQgPSBrcmJfcmRfc2FmZShhZGF0LmRhdCwgYWRhdC5sZW5ndGgsICZkLT5rZXksCiAgICAgICAgICAgICAgICAgICAgKHN0cnVjdCBzb2NrYWRkcl9pbiAqKWhpc2N0bGFkZHIsCiAgICAgICAgICAgICAgICAgICAgKHN0cnVjdCBzb2NrYWRkcl9pbiAqKW15Y3RsYWRkciwgJm1zZ19kYXRhKTsKICBpZihyZXQpIHsKICAgIEN1cmxfZmFpbGYoZGF0YSwgIkVycm9yIHJlYWRpbmcgcmVwbHkgZnJvbSBzZXJ2ZXI6ICVzIiwKICAgICAgICAgICAgICAga3JiX2dldF9lcnJfdGV4dChyZXQpKTsKICAgIHJldHVybiBBVVRIX0VSUk9SOwogIH0KICBrcmJfZ2V0X2ludChtc2dfZGF0YS5hcHBfZGF0YSwgJmNzLCA0LCAwKTsKICBpZihjcyAtIGNoZWNrc3VtICE9IDEpIHsKICAgIEN1cmxfZmFpbGYoZGF0YSwgIkJhZCBjaGVja3N1bSByZXR1cm5lZCBmcm9tIHNlcnZlciIpOwogICAgcmV0dXJuIEFVVEhfRVJST1I7CiAgfQogIHJldHVybiBBVVRIX09LOwp9CgpzdHJ1Y3QgQ3VybF9zZWNfY2xpZW50X21lY2ggQ3VybF9rcmI0X2NsaWVudF9tZWNoID0gewogICAgIktFUkJFUk9TX1Y0IiwKICAgIHNpemVvZihzdHJ1Y3Qga3JiNF9kYXRhKSwKICAgIE5VTEwsIC8qIGluaXQgKi8KICAgIGtyYjRfYXV0aCwKICAgIE5VTEwsIC8qIGVuZCAqLwogICAga3JiNF9jaGVja19wcm90LAogICAga3JiNF9vdmVyaGVhZCwKICAgIGtyYjRfZW5jb2RlLAogICAga3JiNF9kZWNvZGUKfTsKCkNVUkxjb2RlIEN1cmxfa3JiX2thdXRoKHN0cnVjdCBjb25uZWN0ZGF0YSAqY29ubikKewogIGRlc19jYmxvY2sga2V5OwogIGRlc19rZXlfc2NoZWR1bGUgc2NoZWR1bGU7CiAgS1RFWFRfU1QgdGt0LCB0a3Rjb3B5OwogIGNoYXIgKm5hbWU7CiAgY2hhciAqcDsKICBjaGFyIHBhc3N3ZFsxMDBdOwogIHNpemVfdCB0bXA7CiAgc3NpemVfdCBucmVhZDsKICBpbnQgc2F2ZTsKICBDVVJMY29kZSByZXN1bHQ7CiAgdW5zaWduZWQgY2hhciAqcHRyOwoKICBzYXZlID0gQ3VybF9zZXRfY29tbWFuZF9wcm90KGNvbm4sIHByb3RfcHJpdmF0ZSk7CgogIHJlc3VsdCA9IEN1cmxfZnRwc2VuZGYoY29ubiwgIlNJVEUgS0FVVEggJXMiLCBjb25uLT51c2VyKTsKCiAgaWYocmVzdWx0KQogICAgcmV0dXJuIHJlc3VsdDsKCiAgcmVzdWx0ID0gQ3VybF9HZXRGVFBSZXNwb25zZSgmbnJlYWQsIGNvbm4sIE5VTEwpOwogIGlmKHJlc3VsdCkKICAgIHJldHVybiByZXN1bHQ7CgogIGlmKGNvbm4tPmRhdGEtPnN0YXRlLmJ1ZmZlclswXSAhPSAnMycpewogICAgQ3VybF9zZXRfY29tbWFuZF9wcm90KGNvbm4sIHNhdmUpOwogICAgcmV0dXJuIENVUkxFX0ZUUF9XRUlSRF9TRVJWRVJfUkVQTFk7CiAgfQoKICBwID0gc3Ryc3RyKGNvbm4tPmRhdGEtPnN0YXRlLmJ1ZmZlciwgIlQ9Iik7CiAgaWYoIXApIHsKICAgIEN1cmxfZmFpbGYoY29ubi0+ZGF0YSwgIkJhZCByZXBseSBmcm9tIHNlcnZlciIpOwogICAgQ3VybF9zZXRfY29tbWFuZF9wcm90KGNvbm4sIHNhdmUpOwogICAgcmV0dXJuIENVUkxFX0ZUUF9XRUlSRF9TRVJWRVJfUkVQTFk7CiAgfQoKICBwICs9IDI7CiAgdG1wID0gQ3VybF9iYXNlNjRfZGVjb2RlKHAsICZwdHIpOwogIGlmKHRtcCA+PSBzaXplb2YodGt0LmRhdCkpIHsKICAgIGZyZWUocHRyKTsKICAgIHRtcD0wOwogIH0KICBpZighdG1wIHx8ICFwdHIpIHsKICAgIEN1cmxfZmFpbGYoY29ubi0+ZGF0YSwgIkZhaWxlZCB0byBkZWNvZGUgYmFzZTY0IGluIHJlcGx5LlxuIik7CiAgICBDdXJsX3NldF9jb21tYW5kX3Byb3QoY29ubiwgc2F2ZSk7CiAgICByZXR1cm4gQ1VSTEVfRlRQX1dFSVJEX1NFUlZFUl9SRVBMWTsKICB9CiAgbWVtY3B5KChjaGFyICopdGt0LmRhdCwgcHRyLCB0bXApOwogIGZyZWUocHRyKTsKICB0a3QubGVuZ3RoID0gdG1wOwogIHRrdGNvcHkubGVuZ3RoID0gdGt0Lmxlbmd0aDsKCiAgcCA9IHN0cnN0cihjb25uLT5kYXRhLT5zdGF0ZS5idWZmZXIsICJQPSIpOwogIGlmKCFwKSB7CiAgICBDdXJsX2ZhaWxmKGNvbm4tPmRhdGEsICJCYWQgcmVwbHkgZnJvbSBzZXJ2ZXIiKTsKICAgIEN1cmxfc2V0X2NvbW1hbmRfcHJvdChjb25uLCBzYXZlKTsKICAgIHJldHVybiBDVVJMRV9GVFBfV0VJUkRfU0VSVkVSX1JFUExZOwogIH0KICBuYW1lID0gcCArIDI7CiAgZm9yKDsgKnAgJiYgKnAgIT0gJyAnICYmICpwICE9ICdccicgJiYgKnAgIT0gJ1xuJzsgcCsrKTsKICAqcCA9IDA7CgogIGRlc19zdHJpbmdfdG9fa2V5IChjb25uLT5wYXNzd2QsICZrZXkpOwogIGRlc19rZXlfc2NoZWQoJmtleSwgc2NoZWR1bGUpOwoKICBkZXNfcGNiY19lbmNyeXB0KCh2b2lkICopdGt0LmRhdCwgKHZvaWQgKil0a3Rjb3B5LmRhdCwKICAgICAgICAgICAgICAgICAgIHRrdC5sZW5ndGgsCiAgICAgICAgICAgICAgICAgICBzY2hlZHVsZSwgJmtleSwgREVTX0RFQ1JZUFQpOwogIGlmIChzdHJjbXAgKChjaGFyKil0a3Rjb3B5LmRhdCArIDgsCiAgICAgICAgICAgICAgS1JCX1RJQ0tFVF9HUkFOVElOR19USUNLRVQpICE9IDApIHsKICAgIGFmc19zdHJpbmdfdG9fa2V5KHBhc3N3ZCwKICAgICAgICAgICAgICAgICAgICAgIGtyYl9yZWFsbW9maG9zdChjb25uLT5ob3N0Lm5hbWUpLAogICAgICAgICAgICAgICAgICAgICAgJmtleSk7CiAgICBkZXNfa2V5X3NjaGVkKCZrZXksIHNjaGVkdWxlKTsKICAgIGRlc19wY2JjX2VuY3J5cHQoKHZvaWQgKil0a3QuZGF0LCAodm9pZCAqKXRrdGNvcHkuZGF0LAogICAgICAgICAgICAgICAgICAgICB0a3QubGVuZ3RoLAogICAgICAgICAgICAgICAgICAgICBzY2hlZHVsZSwgJmtleSwgREVTX0RFQ1JZUFQpOwogIH0KICBtZW1zZXQoa2V5LCAwLCBzaXplb2Yoa2V5KSk7CiAgbWVtc2V0KHNjaGVkdWxlLCAwLCBzaXplb2Yoc2NoZWR1bGUpKTsKICBtZW1zZXQocGFzc3dkLCAwLCBzaXplb2YocGFzc3dkKSk7CiAgaWYoQ3VybF9iYXNlNjRfZW5jb2RlKGNvbm4tPmRhdGEsIChjaGFyICopdGt0Y29weS5kYXQsIHRrdGNvcHkubGVuZ3RoLCAmcCkKICAgICA8IDEpIHsKICAgIGZhaWxmKGNvbm4tPmRhdGEsICJPdXQgb2YgbWVtb3J5IGJhc2U2NC1lbmNvZGluZy4iKTsKICAgIEN1cmxfc2V0X2NvbW1hbmRfcHJvdChjb25uLCBzYXZlKTsKICAgIHJldHVybiBDVVJMRV9PVVRfT0ZfTUVNT1JZOwogIH0KICBtZW1zZXQgKHRrdGNvcHkuZGF0LCAwLCB0a3Rjb3B5Lmxlbmd0aCk7CgogIHJlc3VsdCA9IEN1cmxfZnRwc2VuZGYoY29ubiwgIlNJVEUgS0FVVEggJXMgJXMiLCBuYW1lLCBwKTsKICBmcmVlKHApOwogIGlmKHJlc3VsdCkKICAgIHJldHVybiByZXN1bHQ7CgogIHJlc3VsdCA9IEN1cmxfR2V0RlRQUmVzcG9uc2UoJm5yZWFkLCBjb25uLCBOVUxMKTsKICBpZihyZXN1bHQpCiAgICByZXR1cm4gcmVzdWx0OwogIEN1cmxfc2V0X2NvbW1hbmRfcHJvdChjb25uLCBzYXZlKTsKCiAgcmV0dXJuIENVUkxFX09LOwp9CgojZW5kaWYgLyogSEFWRV9LUkI0ICovCiNlbmRpZiAvKiBDVVJMX0RJU0FCTEVfRlRQICovCg==