LyogVGhpcyBzb3VyY2UgY29kZSB3YXMgbW9kaWZpZWQgYnkgTWFydGluIEhlZGVuZmFsayA8bWhlQHN0YWNrZW4ua3RoLnNlPiBmb3IKICogdXNlIGluIEN1cmwuIE1hcnRpbidzIGxhdGVzdCBjaGFuZ2VzIHdlcmUgZG9uZSAyMDAwLTA5LTE4LgogKgogKiBJdCBoYXMgc2luY2UgYmVlbiBwYXRjaGVkIGF3YXkgbGlrZSBhIG1hZG1hbiBieSBEYW5pZWwgU3RlbmJlcmcgdG8gbWFrZSBpdAogKiBiZXR0ZXIgYXBwbGllZCB0byBjdXJsIGNvbmRpdGlvbnMsIGFuZCB0byBtYWtlIGl0IG5vdCB1c2UgZ2xvYmFscywgcG9sbHV0ZQogKiBuYW1lIHNwYWNlIGFuZCBtb3JlLgogKgogKiBDb3B5cmlnaHQgKGMpIDE5OTUsIDE5OTYsIDE5OTcsIDE5OTgsIDE5OTkgS3VuZ2xpZ2EgVGVrbmlza2EgSPZnc2tvbGFuCiAqIChSb3lhbCBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgU3RvY2tob2xtLCBTd2VkZW4pLgogKiBDb3B5cmlnaHQgKGMpIDIwMDQgLSAyMDEwIERhbmllbCBTdGVuYmVyZwogKiBBbGwgcmlnaHRzIHJlc2VydmVkLgogKgogKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCiAqIGFyZSBtZXQ6CiAqCiAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CiAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KICoKICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluIHRoZQogKiAgICBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUgZGlzdHJpYnV0aW9uLgogKgogKiAzLiBOZWl0aGVyIHRoZSBuYW1lIG9mIHRoZSBJbnN0aXR1dGUgbm9yIHRoZSBuYW1lcyBvZiBpdHMgY29udHJpYnV0b3JzCiAqICAgIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZQogKiAgICB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KICoKICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgSU5TVElUVVRFIEFORCBDT05UUklCVVRPUlMgYGBBUyBJUycnIEFORAogKiBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUKICogSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UKICogQVJFIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgSU5TVElUVVRFIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUKICogRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwKICogREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMKICogT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pCiAqIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUCiAqIExJQUJJTElUWSwgT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkKICogT1VUIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgogKiBTVUNIIERBTUFHRS4KICoKICovCgojaW5jbHVkZSAic2V0dXAuaCIKCiNpZm5kZWYgQ1VSTF9ESVNBQkxFX0ZUUAojaWZkZWYgSEFWRV9LUkI0CgojaW5jbHVkZSA8c3RkbGliLmg+CiNpZmRlZiBIQVZFX05FVERCX0gKI2luY2x1ZGUgPG5ldGRiLmg+CiNlbmRpZgojaW5jbHVkZSA8c3RyaW5nLmg+CiNpbmNsdWRlIDxrcmIuaD4KI2luY2x1ZGUgPGRlcy5oPgoKI2lmZGVmIEhBVkVfVU5JU1REX0gKI2luY2x1ZGUgPHVuaXN0ZC5oPiAvKiBmb3IgZ2V0cGlkKCkgKi8KI2VuZGlmCgojaW5jbHVkZSAidXJsZGF0YS5oIgojaW5jbHVkZSAiY3VybF9iYXNlNjQuaCIKI2luY2x1ZGUgImZ0cC5oIgojaW5jbHVkZSAic2VuZGYuaCIKI2luY2x1ZGUgImtyYjQuaCIKI2luY2x1ZGUgImluZXRfbnRvcC5oIgojaW5jbHVkZSAiY3VybF9tZW1vcnkuaCIKCi8qIFRoZSBsYXN0ICNpbmNsdWRlIGZpbGUgc2hvdWxkIGJlOiAqLwojaW5jbHVkZSAibWVtZGVidWcuaCIKCiNkZWZpbmUgTE9DQUxfQUREUiAoJmNvbm4tPmxvY2FsX2FkZHIpCiNkZWZpbmUgUkVNT1RFX0FERFIgY29ubi0+aXBfYWRkci0+YWlfYWRkcgojZGVmaW5lIG15Y3RsYWRkciBMT0NBTF9BRERSCiNkZWZpbmUgaGlzY3RsYWRkciBSRU1PVEVfQUREUgoKc3RydWN0IGtyYjRfZGF0YSB7CiAgZGVzX2NibG9jayBrZXk7CiAgZGVzX2tleV9zY2hlZHVsZSBzY2hlZHVsZTsKICBjaGFyIG5hbWVbQU5BTUVfU1pdOwogIGNoYXIgaW5zdGFuY2VbSU5TVF9TWl07CiAgY2hhciByZWFsbVtSRUFMTV9TWl07Cn07CgojaWZuZGVmIEhBVkVfU1RSTENQWQovKiBpZiBpdCBldmVyIGdvZXMgbm9uLXN0YXRpYywgbWFrZSBpdCBDdXJsXyBwcmVmaXhlZCEgKi8Kc3RhdGljIHNpemVfdApzdHJsY3B5IChjaGFyICpkc3QsIGNvbnN0IGNoYXIgKnNyYywgc2l6ZV90IGRzdF9zeikKewogIHNpemVfdCBuOwogIGNoYXIgKnA7CgogIGZvciAocCA9IGRzdCwgbiA9IDA7CiAgICAgICBuICsgMSA8IGRzdF9zeiAmJiAqc3JjICE9ICdcMCc7CiAgICAgICArK3AsICsrc3JjLCArK24pCiAgICAqcCA9ICpzcmM7CiAgKnAgPSAnXDAnOwogIGlmKCpzcmMgPT0gJ1wwJykKICAgIHJldHVybiBuOwogIGVsc2UKICAgIHJldHVybiBuICsgc3RybGVuIChzcmMpOwp9CiNlbHNlCnNpemVfdCBzdHJsY3B5IChjaGFyICpkc3QsIGNvbnN0IGNoYXIgKnNyYywgc2l6ZV90IGRzdF9zeik7CiNlbmRpZgoKc3RhdGljIGludAprcmI0X2NoZWNrX3Byb3Qodm9pZCAqYXBwX2RhdGEsIGludCBsZXZlbCkKewogIGFwcF9kYXRhID0gTlVMTDsgLyogcHJldmVudCBjb21waWxlciB3YXJuaW5nICovCiAgaWYobGV2ZWwgPT0gUFJPVF9DT05GSURFTlRJQUwpCiAgICByZXR1cm4gLTE7CiAgcmV0dXJuIDA7Cn0KCnN0YXRpYyBpbnQKa3JiNF9kZWNvZGUodm9pZCAqYXBwX2RhdGEsIHZvaWQgKmJ1ZiwgaW50IGxlbiwgaW50IGxldmVsLAogICAgICAgICAgICBzdHJ1Y3QgY29ubmVjdGRhdGEgKmNvbm4pCnsKICBNU0dfREFUIG07CiAgaW50IGU7CiAgc3RydWN0IGtyYjRfZGF0YSAqZCA9IGFwcF9kYXRhOwoKICBpZihsZXZlbCA9PSBQUk9UX1NBRkUpCiAgICBlID0ga3JiX3JkX3NhZmUoYnVmLCBsZW4sICZkLT5rZXksCiAgICAgICAgICAgICAgICAgICAgKHN0cnVjdCBzb2NrYWRkcl9pbiAqKVJFTU9URV9BRERSLAogICAgICAgICAgICAgICAgICAgIChzdHJ1Y3Qgc29ja2FkZHJfaW4gKilMT0NBTF9BRERSLCAmbSk7CiAgZWxzZQogICAgZSA9IGtyYl9yZF9wcml2KGJ1ZiwgbGVuLCBkLT5zY2hlZHVsZSwgJmQtPmtleSwKICAgICAgICAgICAgICAgICAgICAoc3RydWN0IHNvY2thZGRyX2luICopUkVNT1RFX0FERFIsCiAgICAgICAgICAgICAgICAgICAgKHN0cnVjdCBzb2NrYWRkcl9pbiAqKUxPQ0FMX0FERFIsICZtKTsKICBpZihlKSB7CiAgICBzdHJ1Y3QgU2Vzc2lvbkhhbmRsZSAqZGF0YSA9IGNvbm4tPmRhdGE7CiAgICBpbmZvZihkYXRhLCAia3JiNF9kZWNvZGU6ICVzXG4iLCBrcmJfZ2V0X2Vycl90ZXh0KGUpKTsKICAgIHJldHVybiAtMTsKICB9CiAgbWVtbW92ZShidWYsIG0uYXBwX2RhdGEsIG0uYXBwX2xlbmd0aCk7CiAgcmV0dXJuIG0uYXBwX2xlbmd0aDsKfQoKc3RhdGljIGludAprcmI0X292ZXJoZWFkKHZvaWQgKmFwcF9kYXRhLCBpbnQgbGV2ZWwsIGludCBsZW4pCnsKICAvKiBubyBhcmd1bWVudHMgYXJlIHVzZWQsIGp1c3QgaW5pdCB0aGVtIHRvIHByZXZlbnQgY29tcGlsZXIgd2FybmluZ3MgKi8KICBhcHBfZGF0YSA9IE5VTEw7CiAgbGV2ZWwgPSAwOwogIGxlbiA9IDA7CiAgcmV0dXJuIDMxOwp9CgpzdGF0aWMgaW50CmtyYjRfZW5jb2RlKHZvaWQgKmFwcF9kYXRhLCBjb25zdCB2b2lkICpmcm9tLCBpbnQgbGVuZ3RoLCBpbnQgbGV2ZWwsIHZvaWQgKip0bywKICAgICAgICAgICAgc3RydWN0IGNvbm5lY3RkYXRhICpjb25uKQp7CiAgc3RydWN0IGtyYjRfZGF0YSAqZCA9IGFwcF9kYXRhOwogICp0byA9IG1hbGxvYyhsZW5ndGggKyAzMSk7CiAgaWYoISp0bykKICAgIHJldHVybiAtMTsKICBpZihsZXZlbCA9PSBQUk9UX1NBRkUpCiAgICAvKiBOT1RFIHRoYXQgdGhlIHZvaWQqIGNhc3QgaXMgc2FmZSwga3JiX21rX3NhZmUvcHJpdiBkb24ndCBtb2RpZnkgdGhlCiAgICAgKiBpbnB1dCBidWZmZXIKICAgICAqLwogICAgcmV0dXJuIGtyYl9ta19zYWZlKCh2b2lkKilmcm9tLCAqdG8sIGxlbmd0aCwgJmQtPmtleSwKICAgICAgICAgICAgICAgICAgICAgICAoc3RydWN0IHNvY2thZGRyX2luICopTE9DQUxfQUREUiwKICAgICAgICAgICAgICAgICAgICAgICAoc3RydWN0IHNvY2thZGRyX2luICopUkVNT1RFX0FERFIpOwogIGVsc2UgaWYobGV2ZWwgPT0gUFJPVF9QUklWQVRFKQogICAgcmV0dXJuIGtyYl9ta19wcml2KCh2b2lkKilmcm9tLCAqdG8sIGxlbmd0aCwgZC0+c2NoZWR1bGUsICZkLT5rZXksCiAgICAgICAgICAgICAgICAgICAgICAgKHN0cnVjdCBzb2NrYWRkcl9pbiAqKUxPQ0FMX0FERFIsCiAgICAgICAgICAgICAgICAgICAgICAgKHN0cnVjdCBzb2NrYWRkcl9pbiAqKVJFTU9URV9BRERSKTsKICBlbHNlCiAgICByZXR1cm4gLTE7Cn0KCnN0YXRpYyBpbnQKbWtfYXV0aChzdHJ1Y3Qga3JiNF9kYXRhICpkLCBLVEVYVCBhZGF0LAogICAgICAgIGNvbnN0IGNoYXIgKnNlcnZpY2UsIGNoYXIgKmhvc3QsIGludCBjaGVja3N1bSkKewogIGludCByZXQ7CiAgQ1JFREVOVElBTFMgY3JlZDsKICBjaGFyIHNuYW1lW1NOQU1FX1NaXSwgaW5zdFtJTlNUX1NaXSwgcmVhbG1bUkVBTE1fU1pdOwoKICBzdHJsY3B5KHNuYW1lLCBzZXJ2aWNlLCBzaXplb2Yoc25hbWUpKTsKICBzdHJsY3B5KGluc3QsIGtyYl9nZXRfcGhvc3QoaG9zdCksIHNpemVvZihpbnN0KSk7CiAgc3RybGNweShyZWFsbSwga3JiX3JlYWxtb2Zob3N0KGhvc3QpLCBzaXplb2YocmVhbG0pKTsKICByZXQgPSBrcmJfbWtfcmVxKGFkYXQsIHNuYW1lLCBpbnN0LCByZWFsbSwgY2hlY2tzdW0pOwogIGlmKHJldCkKICAgIHJldHVybiByZXQ7CiAgc3RybGNweShzbmFtZSwgc2VydmljZSwgc2l6ZW9mKHNuYW1lKSk7CiAgc3RybGNweShpbnN0LCBrcmJfZ2V0X3Bob3N0KGhvc3QpLCBzaXplb2YoaW5zdCkpOwogIHN0cmxjcHkocmVhbG0sIGtyYl9yZWFsbW9maG9zdChob3N0KSwgc2l6ZW9mKHJlYWxtKSk7CiAgcmV0ID0ga3JiX2dldF9jcmVkKHNuYW1lLCBpbnN0LCByZWFsbSwgJmNyZWQpOwogIG1lbW1vdmUoJmQtPmtleSwgJmNyZWQuc2Vzc2lvbiwgc2l6ZW9mKGRlc19jYmxvY2spKTsKICBkZXNfa2V5X3NjaGVkKCZkLT5rZXksIGQtPnNjaGVkdWxlKTsKICBtZW1zZXQoJmNyZWQsIDAsIHNpemVvZihjcmVkKSk7CiAgcmV0dXJuIHJldDsKfQoKI2lmZGVmIEhBVkVfS1JCX0dFVF9PVVJfSVBfRk9SX1JFQUxNCmludCBrcmJfZ2V0X291cl9pcF9mb3JfcmVhbG0oY2hhciAqLCBzdHJ1Y3QgaW5fYWRkciAqKTsKI2VuZGlmCgpzdGF0aWMgaW50CmtyYjRfYXV0aCh2b2lkICphcHBfZGF0YSwgc3RydWN0IGNvbm5lY3RkYXRhICpjb25uKQp7CiAgaW50IHJldDsKICBjaGFyICpwOwogIHVuc2lnbmVkIGNoYXIgKnB0cjsKICBzaXplX3QgbGVuOwogIEtURVhUX1NUIGFkYXQ7CiAgTVNHX0RBVCBtc2dfZGF0YTsKICBpbnQgY2hlY2tzdW07CiAgdV9pbnQzMl90IGNzOwogIHN0cnVjdCBrcmI0X2RhdGEgKmQgPSBhcHBfZGF0YTsKICBjaGFyICpob3N0ID0gY29ubi0+aG9zdC5uYW1lOwogIHNzaXplX3QgbnJlYWQ7CiAgaW50IGwgPSBzaXplb2YoY29ubi0+bG9jYWxfYWRkcik7CiAgc3RydWN0IFNlc3Npb25IYW5kbGUgKmRhdGEgPSBjb25uLT5kYXRhOwogIENVUkxjb2RlIHJlc3VsdDsKCiAgaWYoZ2V0c29ja25hbWUoY29ubi0+c29ja1tGSVJTVFNPQ0tFVF0sCiAgICAgICAgICAgICAgICAgKHN0cnVjdCBzb2NrYWRkciAqKUxPQ0FMX0FERFIsICZsKSA8IDApCiAgICBwZXJyb3IoImdldHNvY2tuYW1lKCkiKTsKCiAgY2hlY2tzdW0gPSBnZXRwaWQoKTsKICByZXQgPSBta19hdXRoKGQsICZhZGF0LCAiZnRwIiwgaG9zdCwgY2hlY2tzdW0pOwogIGlmKHJldCA9PSBLRENfUFJfVU5LTk9XTikKICAgIHJldCA9IG1rX2F1dGgoZCwgJmFkYXQsICJyY21kIiwgaG9zdCwgY2hlY2tzdW0pOwogIGlmKHJldCkgewogICAgaW5mb2YoZGF0YSwgIiVzXG4iLCBrcmJfZ2V0X2Vycl90ZXh0KHJldCkpOwogICAgcmV0dXJuIEFVVEhfQ09OVElOVUU7CiAgfQoKI2lmZGVmIEhBVkVfS1JCX0dFVF9PVVJfSVBfRk9SX1JFQUxNCiAgaWYoa3JiX2dldF9jb25maWdfYm9vbCgibmF0X2luX3VzZSIpKSB7CiAgICBzdHJ1Y3Qgc29ja2FkZHJfaW4gKmxvY2FsYWRkciAgPSAoc3RydWN0IHNvY2thZGRyX2luICopTE9DQUxfQUREUjsKICAgIHN0cnVjdCBpbl9hZGRyIG5hdEFkZHI7CgogICAgaWYoa3JiX2dldF9vdXJfaXBfZm9yX3JlYWxtKGtyYl9yZWFsbW9maG9zdChob3N0KSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJm5hdEFkZHIpICE9IEtTVUNDRVNTCiAgICAgICAgJiYga3JiX2dldF9vdXJfaXBfZm9yX3JlYWxtKE5VTEwsICZuYXRBZGRyKSAhPSBLU1VDQ0VTUykKICAgICAgaW5mb2YoZGF0YSwgIkNhbid0IGdldCBhZGRyZXNzIGZvciByZWFsbSAlc1xuIiwKICAgICAgICAgICAgICAgICBrcmJfcmVhbG1vZmhvc3QoaG9zdCkpOwogICAgZWxzZSB7CiAgICAgIGlmKG5hdEFkZHIuc19hZGRyICE9IGxvY2FsYWRkci0+c2luX2FkZHIuc19hZGRyKSB7CiAgICAgICAgY2hhciBhZGRyX2J1ZlsxMjhdOwogICAgICAgIGlmKEN1cmxfaW5ldF9udG9wKEFGX0lORVQsIG5hdEFkZHIsIGFkZHJfYnVmLCBzaXplb2YoYWRkcl9idWYpKSkKICAgICAgICAgIGluZm9mKGRhdGEsICJVc2luZyBOQVQgSVAgYWRkcmVzcyAoJXMpIGZvciBrZXJiZXJvcyA0XG4iLCBhZGRyX2J1Zik7CiAgICAgICAgbG9jYWxhZGRyLT5zaW5fYWRkciA9IG5hdEFkZHI7CiAgICAgIH0KICAgIH0KICB9CiNlbmRpZgoKICBpZihDdXJsX2Jhc2U2NF9lbmNvZGUoY29ubi0+ZGF0YSwgKGNoYXIgKilhZGF0LmRhdCwgYWRhdC5sZW5ndGgsICZwKSA8IDEpIHsKICAgIEN1cmxfZmFpbGYoZGF0YSwgIk91dCBvZiBtZW1vcnkgYmFzZTY0LWVuY29kaW5nIik7CiAgICByZXR1cm4gQVVUSF9DT05USU5VRTsKICB9CgogIHJlc3VsdCA9IEN1cmxfZnRwc2VuZGYoY29ubiwgIkFEQVQgJXMiLCBwKTsKCiAgZnJlZShwKTsKCiAgaWYocmVzdWx0KQogICAgcmV0dXJuIC0yOwoKICBpZihDdXJsX0dldEZUUFJlc3BvbnNlKCZucmVhZCwgY29ubiwgTlVMTCkpCiAgICByZXR1cm4gLTE7CgogIGlmKGRhdGEtPnN0YXRlLmJ1ZmZlclswXSAhPSAnMicpewogICAgQ3VybF9mYWlsZihkYXRhLCAiU2VydmVyIGRpZG4ndCBhY2NlcHQgYXV0aCBkYXRhIik7CiAgICByZXR1cm4gQVVUSF9FUlJPUjsKICB9CgogIHAgPSBzdHJzdHIoZGF0YS0+c3RhdGUuYnVmZmVyLCAiQURBVD0iKTsKICBpZighcCkgewogICAgQ3VybF9mYWlsZihkYXRhLCAiUmVtb3RlIGhvc3QgZGlkbid0IHNlbmQgYWRhdCByZXBseSIpOwogICAgcmV0dXJuIEFVVEhfRVJST1I7CiAgfQogIHAgKz0gNTsKICBsZW4gPSBDdXJsX2Jhc2U2NF9kZWNvZGUocCwgJnB0cik7CiAgaWYobGVuID4gc2l6ZW9mKGFkYXQuZGF0KS0xKSB7CiAgICBmcmVlKHB0cik7CiAgICBsZW49MDsKICB9CiAgaWYoIWxlbiB8fCAhcHRyKSB7CiAgICBDdXJsX2ZhaWxmKGRhdGEsICJGYWlsZWQgdG8gZGVjb2RlIGJhc2U2NCBmcm9tIHNlcnZlciIpOwogICAgcmV0dXJuIEFVVEhfRVJST1I7CiAgfQogIG1lbWNweSgoY2hhciAqKWFkYXQuZGF0LCBwdHIsIGxlbik7CiAgZnJlZShwdHIpOwogIGFkYXQubGVuZ3RoID0gbGVuOwogIHJldCA9IGtyYl9yZF9zYWZlKGFkYXQuZGF0LCBhZGF0Lmxlbmd0aCwgJmQtPmtleSwKICAgICAgICAgICAgICAgICAgICAoc3RydWN0IHNvY2thZGRyX2luICopaGlzY3RsYWRkciwKICAgICAgICAgICAgICAgICAgICAoc3RydWN0IHNvY2thZGRyX2luICopbXljdGxhZGRyLCAmbXNnX2RhdGEpOwogIGlmKHJldCkgewogICAgQ3VybF9mYWlsZihkYXRhLCAiRXJyb3IgcmVhZGluZyByZXBseSBmcm9tIHNlcnZlcjogJXMiLAogICAgICAgICAgICAgICBrcmJfZ2V0X2Vycl90ZXh0KHJldCkpOwogICAgcmV0dXJuIEFVVEhfRVJST1I7CiAgfQogIGtyYl9nZXRfaW50KG1zZ19kYXRhLmFwcF9kYXRhLCAmY3MsIDQsIDApOwogIGlmKGNzIC0gY2hlY2tzdW0gIT0gMSkgewogICAgQ3VybF9mYWlsZihkYXRhLCAiQmFkIGNoZWNrc3VtIHJldHVybmVkIGZyb20gc2VydmVyIik7CiAgICByZXR1cm4gQVVUSF9FUlJPUjsKICB9CiAgcmV0dXJuIEFVVEhfT0s7Cn0KCnN0cnVjdCBDdXJsX3NlY19jbGllbnRfbWVjaCBDdXJsX2tyYjRfY2xpZW50X21lY2ggPSB7CiAgICAiS0VSQkVST1NfVjQiLAogICAgc2l6ZW9mKHN0cnVjdCBrcmI0X2RhdGEpLAogICAgTlVMTCwgLyogaW5pdCAqLwogICAga3JiNF9hdXRoLAogICAgTlVMTCwgLyogZW5kICovCiAgICBrcmI0X2NoZWNrX3Byb3QsCiAgICBrcmI0X292ZXJoZWFkLAogICAga3JiNF9lbmNvZGUsCiAgICBrcmI0X2RlY29kZQp9OwoKc3RhdGljIGVudW0gcHJvdGVjdGlvbl9sZXZlbAprcmI0X3NldF9jb21tYW5kX3Byb3Qoc3RydWN0IGNvbm5lY3RkYXRhICpjb25uLCBlbnVtIHByb3RlY3Rpb25fbGV2ZWwgbGV2ZWwpCnsKICBlbnVtIHByb3RlY3Rpb25fbGV2ZWwgb2xkID0gY29ubi0+Y29tbWFuZF9wcm90OwogIERFQlVHQVNTRVJUKGxldmVsID4gUFJPVF9OT05FICYmIGxldmVsIDwgUFJPVF9MQVNUKTsKICBjb25uLT5jb21tYW5kX3Byb3QgPSBsZXZlbDsKICByZXR1cm4gb2xkOwp9CgpDVVJMY29kZSBDdXJsX2tyYl9rYXV0aChzdHJ1Y3QgY29ubmVjdGRhdGEgKmNvbm4pCnsKICBkZXNfY2Jsb2NrIGtleTsKICBkZXNfa2V5X3NjaGVkdWxlIHNjaGVkdWxlOwogIEtURVhUX1NUIHRrdCwgdGt0Y29weTsKICBjaGFyICpuYW1lOwogIGNoYXIgKnA7CiAgY2hhciBwYXNzd2RbMTAwXTsKICBzaXplX3QgdG1wOwogIHNzaXplX3QgbnJlYWQ7CiAgZW51bSBwcm90ZWN0aW9uX2xldmVsIHNhdmU7CiAgQ1VSTGNvZGUgcmVzdWx0OwogIHVuc2lnbmVkIGNoYXIgKnB0cjsKCiAgc2F2ZSA9IGtyYjRfc2V0X2NvbW1hbmRfcHJvdChjb25uLCBQUk9UX1BSSVZBVEUpOwoKICByZXN1bHQgPSBDdXJsX2Z0cHNlbmRmKGNvbm4sICJTSVRFIEtBVVRIICVzIiwgY29ubi0+dXNlcik7CgogIGlmKHJlc3VsdCkKICAgIHJldHVybiByZXN1bHQ7CgogIHJlc3VsdCA9IEN1cmxfR2V0RlRQUmVzcG9uc2UoJm5yZWFkLCBjb25uLCBOVUxMKTsKICBpZihyZXN1bHQpCiAgICByZXR1cm4gcmVzdWx0OwoKICBpZihjb25uLT5kYXRhLT5zdGF0ZS5idWZmZXJbMF0gIT0gJzMnKXsKICAgIGtyYjRfc2V0X2NvbW1hbmRfcHJvdChjb25uLCBzYXZlKTsKICAgIHJldHVybiBDVVJMRV9GVFBfV0VJUkRfU0VSVkVSX1JFUExZOwogIH0KCiAgcCA9IHN0cnN0cihjb25uLT5kYXRhLT5zdGF0ZS5idWZmZXIsICJUPSIpOwogIGlmKCFwKSB7CiAgICBDdXJsX2ZhaWxmKGNvbm4tPmRhdGEsICJCYWQgcmVwbHkgZnJvbSBzZXJ2ZXIiKTsKICAgIGtyYjRfc2V0X2NvbW1hbmRfcHJvdChjb25uLCBzYXZlKTsKICAgIHJldHVybiBDVVJMRV9GVFBfV0VJUkRfU0VSVkVSX1JFUExZOwogIH0KCiAgcCArPSAyOwogIHRtcCA9IEN1cmxfYmFzZTY0X2RlY29kZShwLCAmcHRyKTsKICBpZih0bXAgPj0gc2l6ZW9mKHRrdC5kYXQpKSB7CiAgICBmcmVlKHB0cik7CiAgICB0bXA9MDsKICB9CiAgaWYoIXRtcCB8fCAhcHRyKSB7CiAgICBDdXJsX2ZhaWxmKGNvbm4tPmRhdGEsICJGYWlsZWQgdG8gZGVjb2RlIGJhc2U2NCBpbiByZXBseSIpOwogICAga3JiNF9zZXRfY29tbWFuZF9wcm90KGNvbm4sIHNhdmUpOwogICAgcmV0dXJuIENVUkxFX0ZUUF9XRUlSRF9TRVJWRVJfUkVQTFk7CiAgfQogIG1lbWNweSgoY2hhciAqKXRrdC5kYXQsIHB0ciwgdG1wKTsKICBmcmVlKHB0cik7CiAgdGt0Lmxlbmd0aCA9IHRtcDsKICB0a3Rjb3B5Lmxlbmd0aCA9IHRrdC5sZW5ndGg7CgogIHAgPSBzdHJzdHIoY29ubi0+ZGF0YS0+c3RhdGUuYnVmZmVyLCAiUD0iKTsKICBpZighcCkgewogICAgQ3VybF9mYWlsZihjb25uLT5kYXRhLCAiQmFkIHJlcGx5IGZyb20gc2VydmVyIik7CiAgICBrcmI0X3NldF9jb21tYW5kX3Byb3QoY29ubiwgc2F2ZSk7CiAgICByZXR1cm4gQ1VSTEVfRlRQX1dFSVJEX1NFUlZFUl9SRVBMWTsKICB9CiAgbmFtZSA9IHAgKyAyOwogIGZvcig7ICpwICYmICpwICE9ICcgJyAmJiAqcCAhPSAnXHInICYmICpwICE9ICdcbic7IHArKyk7CiAgKnAgPSAwOwoKICBkZXNfc3RyaW5nX3RvX2tleSAoY29ubi0+cGFzc3dkLCAma2V5KTsKICBkZXNfa2V5X3NjaGVkKCZrZXksIHNjaGVkdWxlKTsKCiAgZGVzX3BjYmNfZW5jcnlwdCgodm9pZCAqKXRrdC5kYXQsICh2b2lkICopdGt0Y29weS5kYXQsCiAgICAgICAgICAgICAgICAgICB0a3QubGVuZ3RoLAogICAgICAgICAgICAgICAgICAgc2NoZWR1bGUsICZrZXksIERFU19ERUNSWVBUKTsKICBpZihzdHJjbXAgKChjaGFyKil0a3Rjb3B5LmRhdCArIDgsCiAgICAgICAgICAgICAgS1JCX1RJQ0tFVF9HUkFOVElOR19USUNLRVQpICE9IDApIHsKICAgIGFmc19zdHJpbmdfdG9fa2V5KHBhc3N3ZCwKICAgICAgICAgICAgICAgICAgICAgIGtyYl9yZWFsbW9maG9zdChjb25uLT5ob3N0Lm5hbWUpLAogICAgICAgICAgICAgICAgICAgICAgJmtleSk7CiAgICBkZXNfa2V5X3NjaGVkKCZrZXksIHNjaGVkdWxlKTsKICAgIGRlc19wY2JjX2VuY3J5cHQoKHZvaWQgKil0a3QuZGF0LCAodm9pZCAqKXRrdGNvcHkuZGF0LAogICAgICAgICAgICAgICAgICAgICB0a3QubGVuZ3RoLAogICAgICAgICAgICAgICAgICAgICBzY2hlZHVsZSwgJmtleSwgREVTX0RFQ1JZUFQpOwogIH0KICBtZW1zZXQoa2V5LCAwLCBzaXplb2Yoa2V5KSk7CiAgbWVtc2V0KHNjaGVkdWxlLCAwLCBzaXplb2Yoc2NoZWR1bGUpKTsKICBtZW1zZXQocGFzc3dkLCAwLCBzaXplb2YocGFzc3dkKSk7CiAgaWYoQ3VybF9iYXNlNjRfZW5jb2RlKGNvbm4tPmRhdGEsIChjaGFyICopdGt0Y29weS5kYXQsIHRrdGNvcHkubGVuZ3RoLCAmcCkKICAgICA8IDEpIHsKICAgIGZhaWxmKGNvbm4tPmRhdGEsICJPdXQgb2YgbWVtb3J5IGJhc2U2NC1lbmNvZGluZy4iKTsKICAgIGtyYjRfc2V0X2NvbW1hbmRfcHJvdChjb25uLCBzYXZlKTsKICAgIHJldHVybiBDVVJMRV9PVVRfT0ZfTUVNT1JZOwogIH0KICBtZW1zZXQgKHRrdGNvcHkuZGF0LCAwLCB0a3Rjb3B5Lmxlbmd0aCk7CgogIHJlc3VsdCA9IEN1cmxfZnRwc2VuZGYoY29ubiwgIlNJVEUgS0FVVEggJXMgJXMiLCBuYW1lLCBwKTsKICBmcmVlKHApOwogIGlmKHJlc3VsdCkKICAgIHJldHVybiByZXN1bHQ7CgogIHJlc3VsdCA9IEN1cmxfR2V0RlRQUmVzcG9uc2UoJm5yZWFkLCBjb25uLCBOVUxMKTsKICBpZihyZXN1bHQpCiAgICByZXR1cm4gcmVzdWx0OwogIGtyYjRfc2V0X2NvbW1hbmRfcHJvdChjb25uLCBzYXZlKTsKCiAgcmV0dXJuIENVUkxFX09LOwp9CgojZW5kaWYgLyogSEFWRV9LUkI0ICovCiNlbmRpZiAvKiBDVVJMX0RJU0FCTEVfRlRQICovCg==