LyoKICogQ09NIHByb3h5L3N0dWIgZmFjdG9yeSAoQ1N0ZFBTRmFjdG9yeSkgaW1wbGVtZW50YXRpb24KICoKICogQ29weXJpZ2h0IDIwMDEgT3ZlIEvldmVuLCBUcmFuc0dhbWluZyBUZWNobm9sb2dpZXMKICoKICogVGhpcyBsaWJyYXJ5IGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vcgogKiBtb2RpZnkgaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljCiAqIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlcgogKiB2ZXJzaW9uIDIuMSBvZiB0aGUgTGljZW5zZSwgb3IgKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi4KICoKICogVGhpcyBsaWJyYXJ5IGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsCiAqIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mCiAqIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VCiAqIExlc3NlciBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMKICogTGljZW5zZSBhbG9uZyB3aXRoIHRoaXMgbGlicmFyeTsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZQogKiBGb3VuZGF0aW9uLCBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSwgVVNBCiAqLwoKI2luY2x1ZGUgImNvbmZpZy5oIgojaW5jbHVkZSAid2luZS9wb3J0LmgiCgojaW5jbHVkZSA8c3RkYXJnLmg+CiNpbmNsdWRlIDxzdGRpby5oPgojaW5jbHVkZSA8c3RyaW5nLmg+CgojZGVmaW5lIENPQkpNQUNST1MKCiNpbmNsdWRlICJ3aW5kZWYuaCIKI2luY2x1ZGUgIndpbmJhc2UuaCIKI2luY2x1ZGUgIndpbmVycm9yLmgiCiNpbmNsdWRlICJ3aW5yZWcuaCIKCiNpbmNsdWRlICJvYmpiYXNlLmgiCgojaW5jbHVkZSAicnBjcHJveHkuaCIKCiNpbmNsdWRlICJ3aW5lL2RlYnVnLmgiCgojaW5jbHVkZSAiY3BzZi5oIgoKV0lORV9ERUZBVUxUX0RFQlVHX0NIQU5ORUwob2xlKTsKCnN0YXRpYyBCT09MIEZpbmRQcm94eUluZm8oY29uc3QgUHJveHlGaWxlSW5mbyAqKnBQcm94eUZpbGVMaXN0LCBSRUZJSUQgcmlpZCwgY29uc3QgUHJveHlGaWxlSW5mbyAqKnBQcm94eUluZm8sIGludCAqcEluZGV4KQp7CiAgd2hpbGUgKCpwUHJveHlGaWxlTGlzdCkgewogICAgaWYgKCgqcFByb3h5RmlsZUxpc3QpLT5wSUlETG9va3VwUnRuKHJpaWQsIHBJbmRleCkpIHsKICAgICAgKnBQcm94eUluZm8gPSAqcFByb3h5RmlsZUxpc3Q7CiAgICAgIFRSQUNFKCJmb3VuZDogUHJveHlJbmZvICVwIEluZGV4ICVkXG4iLCAqcFByb3h5SW5mbywgKnBJbmRleCk7CiAgICAgIHJldHVybiBUUlVFOwogICAgfQogICAgcFByb3h5RmlsZUxpc3QrKzsKICB9CiAgVFJBQ0UoIm5vdCBmb3VuZFxuIik7CiAgcmV0dXJuIEZBTFNFOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgQ1N0ZFBTRmFjdG9yeV9RdWVyeUludGVyZmFjZShMUFBTRkFDVE9SWUJVRkZFUiBpZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBSRUZJSUQgcmlpZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUFZPSUQgKm9iaikKewogIENTdGRQU0ZhY3RvcnlCdWZmZXIgKlRoaXMgPSAoQ1N0ZFBTRmFjdG9yeUJ1ZmZlciAqKWlmYWNlOwogIFRSQUNFKCIoJXApLT5RdWVyeUludGVyZmFjZSglcywlcClcbiIsaWZhY2UsZGVidWdzdHJfZ3VpZChyaWlkKSxvYmopOwogIGlmIChJc0VxdWFsR1VJRCgmSUlEX0lVbmtub3duLHJpaWQpIHx8CiAgICAgIElzRXF1YWxHVUlEKCZJSURfSVBTRmFjdG9yeUJ1ZmZlcixyaWlkKSkgewogICAgKm9iaiA9IFRoaXM7CiAgICBUaGlzLT5SZWZDb3VudCsrOwogICAgcmV0dXJuIFNfT0s7CiAgfQogIHJldHVybiBFX05PSU5URVJGQUNFOwp9CgpzdGF0aWMgVUxPTkcgV0lOQVBJIENTdGRQU0ZhY3RvcnlfQWRkUmVmKExQUFNGQUNUT1JZQlVGRkVSIGlmYWNlKQp7CiAgQ1N0ZFBTRmFjdG9yeUJ1ZmZlciAqVGhpcyA9IChDU3RkUFNGYWN0b3J5QnVmZmVyICopaWZhY2U7CiAgVFJBQ0UoIiglcCktPkFkZFJlZigpXG4iLGlmYWNlKTsKICByZXR1cm4gKysoVGhpcy0+UmVmQ291bnQpOwp9CgpzdGF0aWMgVUxPTkcgV0lOQVBJIENTdGRQU0ZhY3RvcnlfUmVsZWFzZShMUFBTRkFDVE9SWUJVRkZFUiBpZmFjZSkKewogIENTdGRQU0ZhY3RvcnlCdWZmZXIgKlRoaXMgPSAoQ1N0ZFBTRmFjdG9yeUJ1ZmZlciAqKWlmYWNlOwogIFRSQUNFKCIoJXApLT5SZWxlYXNlKClcbiIsaWZhY2UpOwogIHJldHVybiAtLShUaGlzLT5SZWZDb3VudCk7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBDU3RkUFNGYWN0b3J5X0NyZWF0ZVByb3h5KExQUFNGQUNUT1JZQlVGRkVSIGlmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQVU5LTk9XTiBwVW5rT3V0ZXIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUkVGSUlEIHJpaWQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBSUENQUk9YWUJVRkZFUiAqcHBQcm94eSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUFZPSUQgKnBwdikKewogIENTdGRQU0ZhY3RvcnlCdWZmZXIgKlRoaXMgPSAoQ1N0ZFBTRmFjdG9yeUJ1ZmZlciAqKWlmYWNlOwogIGNvbnN0IFByb3h5RmlsZUluZm8gKlByb3h5SW5mbzsKICBpbnQgSW5kZXg7CiAgVFJBQ0UoIiglcCktPkNyZWF0ZVByb3h5KCVwLCVzLCVwLCVwKVxuIixpZmFjZSxwVW5rT3V0ZXIsCiAgICAgICBkZWJ1Z3N0cl9ndWlkKHJpaWQpLHBwUHJveHkscHB2KTsKICBpZiAoIUZpbmRQcm94eUluZm8oVGhpcy0+cFByb3h5RmlsZUxpc3QscmlpZCwmUHJveHlJbmZvLCZJbmRleCkpCiAgICByZXR1cm4gRV9OT0lOVEVSRkFDRTsKICByZXR1cm4gU3RkUHJveHlfQ29uc3RydWN0KHJpaWQsIHBVbmtPdXRlciwgUHJveHlJbmZvLCBJbmRleCwgaWZhY2UsIHBwUHJveHksIHBwdik7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBDU3RkUFNGYWN0b3J5X0NyZWF0ZVN0dWIoTFBQU0ZBQ1RPUllCVUZGRVIgaWZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBSRUZJSUQgcmlpZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQVU5LTk9XTiBwVW5rU2VydmVyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBSUENTVFVCQlVGRkVSICpwcFN0dWIpCnsKICBDU3RkUFNGYWN0b3J5QnVmZmVyICpUaGlzID0gKENTdGRQU0ZhY3RvcnlCdWZmZXIgKilpZmFjZTsKICBjb25zdCBQcm94eUZpbGVJbmZvICpQcm94eUluZm87CiAgaW50IEluZGV4OwogIFRSQUNFKCIoJXApLT5DcmVhdGVTdHViKCVzLCVwLCVwKVxuIixpZmFjZSxkZWJ1Z3N0cl9ndWlkKHJpaWQpLAogICAgICAgcFVua1NlcnZlcixwcFN0dWIpOwogIGlmICghRmluZFByb3h5SW5mbyhUaGlzLT5wUHJveHlGaWxlTGlzdCxyaWlkLCZQcm94eUluZm8sJkluZGV4KSkKICAgIHJldHVybiBFX05PSU5URVJGQUNFOwoKICBpZihQcm94eUluZm8tPnBEZWxlZ2F0ZWRJSURzICYmIFByb3h5SW5mby0+cERlbGVnYXRlZElJRHNbSW5kZXhdKQogICAgcmV0dXJuICBDU3RkU3R1YkJ1ZmZlcl9EZWxlZ2F0aW5nX0NvbnN0cnVjdChyaWlkLCBwVW5rU2VydmVyLCBQcm94eUluZm8tPnBOYW1lc0FycmF5W0luZGV4XSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUHJveHlJbmZvLT5wU3R1YlZ0YmxMaXN0W0luZGV4XSwgUHJveHlJbmZvLT5wRGVsZWdhdGVkSUlEc1tJbmRleF0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmYWNlLCBwcFN0dWIpOwoKICByZXR1cm4gQ1N0ZFN0dWJCdWZmZXJfQ29uc3RydWN0KHJpaWQsIHBVbmtTZXJ2ZXIsIFByb3h5SW5mby0+cE5hbWVzQXJyYXlbSW5kZXhdLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUHJveHlJbmZvLT5wU3R1YlZ0YmxMaXN0W0luZGV4XSwgaWZhY2UsIHBwU3R1Yik7Cn0KCnN0YXRpYyBjb25zdCBJUFNGYWN0b3J5QnVmZmVyVnRibCBDU3RkUFNGYWN0b3J5X1Z0YmwgPQp7CiAgQ1N0ZFBTRmFjdG9yeV9RdWVyeUludGVyZmFjZSwKICBDU3RkUFNGYWN0b3J5X0FkZFJlZiwKICBDU3RkUFNGYWN0b3J5X1JlbGVhc2UsCiAgQ1N0ZFBTRmFjdG9yeV9DcmVhdGVQcm94eSwKICBDU3RkUFNGYWN0b3J5X0NyZWF0ZVN0dWIKfTsKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgTmRyRGxsR2V0Q2xhc3NPYmplY3QgW1JQQ1JUNC5AXQogKi8KSFJFU1VMVCBXSU5BUEkgTmRyRGxsR2V0Q2xhc3NPYmplY3QoUkVGQ0xTSUQgcmNsc2lkLCBSRUZJSUQgaWlkLCBMUFZPSUQgKnBwdiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBQcm94eUZpbGVJbmZvICoqcFByb3h5RmlsZUxpc3QsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgQ0xTSUQgKnBjbHNpZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBDU3RkUFNGYWN0b3J5QnVmZmVyICpwUFNGYWN0b3J5QnVmZmVyKQp7CiAgVFJBQ0UoIiglcywgJXMsICVwLCAlcCwgJXMsICVwKVxuIiwgZGVidWdzdHJfZ3VpZChyY2xzaWQpLAogICAgZGVidWdzdHJfZ3VpZChpaWQpLCBwcHYsIHBQcm94eUZpbGVMaXN0LCBkZWJ1Z3N0cl9ndWlkKHBjbHNpZCksCiAgICBwUFNGYWN0b3J5QnVmZmVyKTsKCiAgKnBwdiA9IE5VTEw7CiAgaWYgKCFwUFNGYWN0b3J5QnVmZmVyLT5scFZ0YmwpIHsKICAgIGNvbnN0IFByb3h5RmlsZUluZm8gKipwUHJveHlGaWxlTGlzdDI7CiAgICBpbnQgbWF4X2RlbGVnYXRpbmdfdnRibF9zaXplID0gMDsKICAgIHBQU0ZhY3RvcnlCdWZmZXItPmxwVnRibCA9ICZDU3RkUFNGYWN0b3J5X1Z0Ymw7CiAgICBwUFNGYWN0b3J5QnVmZmVyLT5SZWZDb3VudCA9IDA7CiAgICBwUFNGYWN0b3J5QnVmZmVyLT5wUHJveHlGaWxlTGlzdCA9IHBQcm94eUZpbGVMaXN0OwogICAgZm9yIChwUHJveHlGaWxlTGlzdDIgPSBwUHJveHlGaWxlTGlzdDsgKnBQcm94eUZpbGVMaXN0MjsgcFByb3h5RmlsZUxpc3QyKyspIHsKICAgICAgaW50IGk7CiAgICAgIGZvciAoaSA9IDA7IGkgPCAoKnBQcm94eUZpbGVMaXN0MiktPlRhYmxlU2l6ZTsgaSsrKSB7CiAgICAgICAgLyogRklYTUU6IGkgdGhpbmsgdGhhdCBkaWZmZXJlbnQgdnRhYmxlcyBzaG91bGQgYmUgY29waWVkIGZvcgogICAgICAgICAqIGFzeW5jIGludGVyZmFjZXMgKi8KICAgICAgICB2b2lkICogY29uc3QgKnBTcmNScGNTdHViVnRibCA9ICh2b2lkICogY29uc3QgKikmQ1N0ZFN0dWJCdWZmZXJfVnRibDsKICAgICAgICB2b2lkICoqcFJwY1N0dWJWdGJsID0gKHZvaWQgKiopJigqcFByb3h5RmlsZUxpc3QyKS0+cFN0dWJWdGJsTGlzdFtpXS0+VnRibDsKICAgICAgICBpbnQgajsKCiAgICAgICAgaWYgKCgqcFByb3h5RmlsZUxpc3QyKS0+cERlbGVnYXRlZElJRHMgJiYgKCpwUHJveHlGaWxlTGlzdDIpLT5wRGVsZWdhdGVkSUlEc1tpXSkgewogICAgICAgICAgcFNyY1JwY1N0dWJWdGJsID0gKHZvaWQgKiBjb25zdCAqKSZDU3RkU3R1YkJ1ZmZlcl9EZWxlZ2F0aW5nX1Z0Ymw7CiAgICAgICAgICBpZiAoKCpwUHJveHlGaWxlTGlzdDIpLT5wU3R1YlZ0YmxMaXN0W2ldLT5oZWFkZXIuRGlzcGF0Y2hUYWJsZUNvdW50ID4gbWF4X2RlbGVnYXRpbmdfdnRibF9zaXplKQogICAgICAgICAgICBtYXhfZGVsZWdhdGluZ192dGJsX3NpemUgPSAoKnBQcm94eUZpbGVMaXN0MiktPnBTdHViVnRibExpc3RbaV0tPmhlYWRlci5EaXNwYXRjaFRhYmxlQ291bnQ7CiAgICAgICAgfQoKICAgICAgICBmb3IgKGogPSAwOyBqIDwgc2l6ZW9mKElScGNTdHViQnVmZmVyVnRibCkvc2l6ZW9mKHZvaWQgKik7IGorKykKICAgICAgICAgIGlmICghcFJwY1N0dWJWdGJsW2pdKQogICAgICAgICAgICBwUnBjU3R1YlZ0Ymxbal0gPSBwU3JjUnBjU3R1YlZ0Ymxbal07CiAgICAgIH0KICAgIH0KICAgIGlmKG1heF9kZWxlZ2F0aW5nX3Z0Ymxfc2l6ZSA+IDApCiAgICAgIGNyZWF0ZV9kZWxlZ2F0aW5nX3Z0YmwobWF4X2RlbGVnYXRpbmdfdnRibF9zaXplKTsKICB9CiAgaWYgKElzRXF1YWxHVUlEKHJjbHNpZCwgcGNsc2lkKSkKICAgIHJldHVybiBJUFNGYWN0b3J5QnVmZmVyX1F1ZXJ5SW50ZXJmYWNlKChMUFBTRkFDVE9SWUJVRkZFUilwUFNGYWN0b3J5QnVmZmVyLCBpaWQsIHBwdik7CiAgZWxzZSB7CiAgICBjb25zdCBQcm94eUZpbGVJbmZvICppbmZvOwogICAgaW50IGluZGV4OwogICAgLyogb3RoZXJ3aXNlLCB0aGUgZGxsIG1heSBiZSB1c2luZyB0aGUgaWlkIGFzIHRoZSBjbHNpZCwgc28KICAgICAqIHNlYXJjaCBmb3IgaXQgaW4gdGhlIHByb3h5IGZpbGUgbGlzdCAqLwogICAgaWYgKEZpbmRQcm94eUluZm8ocFByb3h5RmlsZUxpc3QsIHJjbHNpZCwgJmluZm8sICZpbmRleCkpCiAgICAgIHJldHVybiBJUFNGYWN0b3J5QnVmZmVyX1F1ZXJ5SW50ZXJmYWNlKChMUFBTRkFDVE9SWUJVRkZFUilwUFNGYWN0b3J5QnVmZmVyLCBpaWQsIHBwdik7CgogICAgV0FSTigiY2xhc3MgJXMgbm90IGF2YWlsYWJsZVxuIiwgZGVidWdzdHJfZ3VpZChyY2xzaWQpKTsKICAgIHJldHVybiBDTEFTU19FX0NMQVNTTk9UQVZBSUxBQkxFOwogIH0KfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICBOZHJEbGxDYW5VbmxvYWROb3cgW1JQQ1JUNC5AXQogKi8KSFJFU1VMVCBXSU5BUEkgTmRyRGxsQ2FuVW5sb2FkTm93KENTdGRQU0ZhY3RvcnlCdWZmZXIgKnBQU0ZhY3RvcnlCdWZmZXIpCnsKICByZXR1cm4gIShwUFNGYWN0b3J5QnVmZmVyLT5SZWZDb3VudCk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgTmRyRGxsUmVnaXN0ZXJQcm94eSBbUlBDUlQ0LkBdCiAqLwpIUkVTVUxUIFdJTkFQSSBOZHJEbGxSZWdpc3RlclByb3h5KEhNT0RVTEUgaERsbCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IFByb3h5RmlsZUluZm8gKipwUHJveHlGaWxlTGlzdCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IENMU0lEICpwY2xzaWQpCnsKICBMUFNUUiBjbHNpZDsKICBjaGFyIGtleW5hbWVbMTIwXSwgbW9kdWxlW01BWF9QQVRIXTsKICBIS0VZIGtleSwgc3Via2V5OwogIERXT1JEIGxlbjsKCiAgVFJBQ0UoIiglcCwlcCwlcylcbiIsIGhEbGwsIHBQcm94eUZpbGVMaXN0LCBkZWJ1Z3N0cl9ndWlkKHBjbHNpZCkpOwogIFV1aWRUb1N0cmluZ0EoKFVVSUQqKXBjbHNpZCwgKHVuc2lnbmVkIGNoYXIqKikmY2xzaWQpOwoKICAvKiByZWdpc3RlciBpbnRlcmZhY2VzIHRvIHBvaW50IHRvIGNsc2lkICovCiAgd2hpbGUgKCpwUHJveHlGaWxlTGlzdCkgewogICAgdW5zaWduZWQgdTsKICAgIGZvciAodT0wOyB1PCgqcFByb3h5RmlsZUxpc3QpLT5UYWJsZVNpemU7IHUrKykgewogICAgICBDSW50ZXJmYWNlU3R1YlZ0YmwgKnByb3h5ID0gKCpwUHJveHlGaWxlTGlzdCktPnBTdHViVnRibExpc3RbdV07CiAgICAgIFBDSW50ZXJmYWNlTmFtZSBuYW1lID0gKCpwUHJveHlGaWxlTGlzdCktPnBOYW1lc0FycmF5W3VdOwogICAgICBMUFNUUiBpaWQ7CgogICAgICBUUkFDRSgicmVnaXN0ZXJpbmcgJXMgJXMgPT4gJXNcbiIsIG5hbWUsIGRlYnVnc3RyX2d1aWQocHJveHktPmhlYWRlci5waWlkKSwgY2xzaWQpOwoKICAgICAgVXVpZFRvU3RyaW5nQSgoVVVJRCopcHJveHktPmhlYWRlci5waWlkLCAodW5zaWduZWQgY2hhcioqKSZpaWQpOwogICAgICBzbnByaW50ZihrZXluYW1lLCBzaXplb2Yoa2V5bmFtZSksICJJbnRlcmZhY2VcXHslc30iLCBpaWQpOwogICAgICBScGNTdHJpbmdGcmVlQSgodW5zaWduZWQgY2hhcioqKSZpaWQpOwogICAgICBpZiAoUmVnQ3JlYXRlS2V5RXhBKEhLRVlfQ0xBU1NFU19ST09ULCBrZXluYW1lLCAwLCBOVUxMLCAwLAogICAgICAgICAgICAgICAgICAgICAgICAgIEtFWV9XUklURSwgTlVMTCwgJmtleSwgTlVMTCkgPT0gRVJST1JfU1VDQ0VTUykgewogICAgICAgIGlmIChuYW1lKQogICAgICAgICAgUmVnU2V0VmFsdWVFeEEoa2V5LCBOVUxMLCAwLCBSRUdfU1osIChjb25zdCBCWVRFICopbmFtZSwgc3RybGVuKG5hbWUpKTsKICAgICAgICBpZiAoUmVnQ3JlYXRlS2V5RXhBKGtleSwgIlByb3h5U3R1YkNsc2lkMzIiLCAwLCBOVUxMLCAwLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgS0VZX1dSSVRFLCBOVUxMLCAmc3Via2V5LCBOVUxMKSA9PSBFUlJPUl9TVUNDRVNTKSB7CiAgICAgICAgICBzbnByaW50Zihtb2R1bGUsIHNpemVvZihtb2R1bGUpLCAieyVzfSIsIGNsc2lkKTsKICAgICAgICAgIFJlZ1NldFZhbHVlRXhBKHN1YmtleSwgTlVMTCwgMCwgUkVHX1NaLCAoTFBCWVRFKW1vZHVsZSwgc3RybGVuKG1vZHVsZSkpOwogICAgICAgICAgUmVnQ2xvc2VLZXkoc3Via2V5KTsKICAgICAgICB9CiAgICAgICAgUmVnQ2xvc2VLZXkoa2V5KTsKICAgICAgfQogICAgfQogICAgcFByb3h5RmlsZUxpc3QrKzsKICB9CgogIC8qIHJlZ2lzdGVyIGNsc2lkIHRvIHBvaW50IHRvIG1vZHVsZSAqLwogIHNucHJpbnRmKGtleW5hbWUsIHNpemVvZihrZXluYW1lKSwgIkNMU0lEXFx7JXN9IiwgY2xzaWQpOwogIGxlbiA9IEdldE1vZHVsZUZpbGVOYW1lQShoRGxsLCBtb2R1bGUsIHNpemVvZihtb2R1bGUpKTsKICBpZiAobGVuICYmIGxlbiA8IHNpemVvZihtb2R1bGUpKSB7CiAgICBUUkFDRSgicmVnaXN0ZXJpbmcgQ0xTSUQgJXMgPT4gJXNcbiIsIGNsc2lkLCBtb2R1bGUpOwogICAgaWYgKFJlZ0NyZWF0ZUtleUV4QShIS0VZX0NMQVNTRVNfUk9PVCwga2V5bmFtZSwgMCwgTlVMTCwgMCwKICAgICAgICAgICAgICAgICAgICAgICAgS0VZX1dSSVRFLCBOVUxMLCAma2V5LCBOVUxMKSA9PSBFUlJPUl9TVUNDRVNTKSB7CiAgICAgIFJlZ1NldFZhbHVlRXhBKHN1YmtleSwgTlVMTCwgMCwgUkVHX1NaLCAoY29uc3QgQllURSAqKSJQU0ZhY3RvcnlCdWZmZXIiLCBzdHJsZW4oIlBTRmFjdG9yeUJ1ZmZlciIpKTsKICAgICAgaWYgKFJlZ0NyZWF0ZUtleUV4QShrZXksICJJblByb2NTZXJ2ZXIzMiIsIDAsIE5VTEwsIDAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgS0VZX1dSSVRFLCBOVUxMLCAmc3Via2V5LCBOVUxMKSA9PSBFUlJPUl9TVUNDRVNTKSB7CiAgICAgICAgUmVnU2V0VmFsdWVFeEEoc3Via2V5LCBOVUxMLCAwLCBSRUdfU1osIChMUEJZVEUpbW9kdWxlLCBzdHJsZW4obW9kdWxlKSk7CiAgICAgICAgUmVnU2V0VmFsdWVFeEEoc3Via2V5LCAiVGhyZWFkaW5nTW9kZWwiLCAwLCBSRUdfU1osIChjb25zdCBCWVRFICopIkJvdGgiLCBzdHJsZW4oIkJvdGgiKSk7CiAgICAgICAgUmVnQ2xvc2VLZXkoc3Via2V5KTsKICAgICAgfQogICAgICBSZWdDbG9zZUtleShrZXkpOwogICAgfQogIH0KCiAgLyogZG9uZSAqLwogIFJwY1N0cmluZ0ZyZWVBKCh1bnNpZ25lZCBjaGFyKiopJmNsc2lkKTsKICByZXR1cm4gU19PSzsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICBOZHJEbGxVbnJlZ2lzdGVyUHJveHkgW1JQQ1JUNC5AXQogKi8KSFJFU1VMVCBXSU5BUEkgTmRyRGxsVW5yZWdpc3RlclByb3h5KEhNT0RVTEUgaERsbCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgUHJveHlGaWxlSW5mbyAqKnBQcm94eUZpbGVMaXN0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBDTFNJRCAqcGNsc2lkKQp7CiAgTFBTVFIgY2xzaWQ7CiAgY2hhciBrZXluYW1lWzEyMF0sIG1vZHVsZVtNQVhfUEFUSF07CiAgRFdPUkQgbGVuOwoKICBUUkFDRSgiKCVwLCVwLCVzKVxuIiwgaERsbCwgcFByb3h5RmlsZUxpc3QsIGRlYnVnc3RyX2d1aWQocGNsc2lkKSk7CiAgVXVpZFRvU3RyaW5nQSgoVVVJRCopcGNsc2lkLCAodW5zaWduZWQgY2hhcioqKSZjbHNpZCk7CgogIC8qIHVucmVnaXN0ZXIgaW50ZXJmYWNlcyAqLwogIHdoaWxlICgqcFByb3h5RmlsZUxpc3QpIHsKICAgIHVuc2lnbmVkIHU7CiAgICBmb3IgKHU9MDsgdTwoKnBQcm94eUZpbGVMaXN0KS0+VGFibGVTaXplOyB1KyspIHsKICAgICAgQ0ludGVyZmFjZVN0dWJWdGJsICpwcm94eSA9ICgqcFByb3h5RmlsZUxpc3QpLT5wU3R1YlZ0YmxMaXN0W3VdOwogICAgICBQQ0ludGVyZmFjZU5hbWUgbmFtZSA9ICgqcFByb3h5RmlsZUxpc3QpLT5wTmFtZXNBcnJheVt1XTsKICAgICAgTFBTVFIgaWlkOwoKICAgICAgVFJBQ0UoInVucmVnaXN0ZXJpbmcgJXMgJXMgPD0gJXNcbiIsIG5hbWUsIGRlYnVnc3RyX2d1aWQocHJveHktPmhlYWRlci5waWlkKSwgY2xzaWQpOwoKICAgICAgVXVpZFRvU3RyaW5nQSgoVVVJRCopcHJveHktPmhlYWRlci5waWlkLCAodW5zaWduZWQgY2hhcioqKSZpaWQpOwogICAgICBzbnByaW50ZihrZXluYW1lLCBzaXplb2Yoa2V5bmFtZSksICJJbnRlcmZhY2VcXHslc30iLCBpaWQpOwogICAgICBScGNTdHJpbmdGcmVlQSgodW5zaWduZWQgY2hhcioqKSZpaWQpOwogICAgICBSZWdEZWxldGVLZXlBKEhLRVlfQ0xBU1NFU19ST09ULCBrZXluYW1lKTsKICAgIH0KICAgIHBQcm94eUZpbGVMaXN0Kys7CiAgfQoKICAvKiB1bnJlZ2lzdGVyIGNsc2lkICovCiAgc25wcmludGYoa2V5bmFtZSwgc2l6ZW9mKGtleW5hbWUpLCAiQ0xTSURcXHslc30iLCBjbHNpZCk7CiAgbGVuID0gR2V0TW9kdWxlRmlsZU5hbWVBKGhEbGwsIG1vZHVsZSwgc2l6ZW9mKG1vZHVsZSkpOwogIGlmIChsZW4gJiYgbGVuIDwgc2l6ZW9mKG1vZHVsZSkpIHsKICAgIFRSQUNFKCJ1bnJlZ2lzdGVyaW5nIENMU0lEICVzIDw9ICVzXG4iLCBjbHNpZCwgbW9kdWxlKTsKICAgIFJlZ0RlbGV0ZUtleUEoSEtFWV9DTEFTU0VTX1JPT1QsIGtleW5hbWUpOwogIH0KCiAgLyogZG9uZSAqLwogIFJwY1N0cmluZ0ZyZWVBKCh1bnNpZ25lZCBjaGFyKiopJmNsc2lkKTsKICByZXR1cm4gU19PSzsKfQo=