LyoKICogQ09NIHByb3h5L3N0dWIgZmFjdG9yeSAoQ1N0ZFBTRmFjdG9yeSkgaW1wbGVtZW50YXRpb24KICoKICogQ29weXJpZ2h0IDIwMDEgT3ZlIEvldmVuLCBUcmFuc0dhbWluZyBUZWNobm9sb2dpZXMKICoKICogVGhpcyBsaWJyYXJ5IGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vcgogKiBtb2RpZnkgaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljCiAqIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlcgogKiB2ZXJzaW9uIDIuMSBvZiB0aGUgTGljZW5zZSwgb3IgKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi4KICoKICogVGhpcyBsaWJyYXJ5IGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsCiAqIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mCiAqIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VCiAqIExlc3NlciBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMKICogTGljZW5zZSBhbG9uZyB3aXRoIHRoaXMgbGlicmFyeTsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZQogKiBGb3VuZGF0aW9uLCBJbmMuLCA1OSBUZW1wbGUgUGxhY2UsIFN1aXRlIDMzMCwgQm9zdG9uLCBNQSAgMDIxMTEtMTMwNyAgVVNBCiAqLwoKI2luY2x1ZGUgPHN0ZGFyZy5oPgojaW5jbHVkZSA8c3RkaW8uaD4KI2luY2x1ZGUgPHN0cmluZy5oPgoKI2RlZmluZSBDT0JKTUFDUk9TCgojaW5jbHVkZSAid2luZGVmLmgiCiNpbmNsdWRlICJ3aW5iYXNlLmgiCiNpbmNsdWRlICJ3aW5lcnJvci5oIgojaW5jbHVkZSAid2lucmVnLmgiCgojaW5jbHVkZSAib2JqYmFzZS5oIgoKI2luY2x1ZGUgInJwY3Byb3h5LmgiCgojaW5jbHVkZSAid2luZS9kZWJ1Zy5oIgoKI2luY2x1ZGUgImNwc2YuaCIKCldJTkVfREVGQVVMVF9ERUJVR19DSEFOTkVMKG9sZSk7CgpzdGF0aWMgQk9PTCBGaW5kUHJveHlJbmZvKGNvbnN0IFByb3h5RmlsZUluZm8gKipwUHJveHlGaWxlTGlzdCwgUkVGSUlEIHJpaWQsIGNvbnN0IFByb3h5RmlsZUluZm8gKipwUHJveHlJbmZvLCBpbnQgKnBJbmRleCkKewogIHdoaWxlICgqcFByb3h5RmlsZUxpc3QpIHsKICAgIGlmICgoKnBQcm94eUZpbGVMaXN0KS0+cElJRExvb2t1cFJ0bihyaWlkLCBwSW5kZXgpKSB7CiAgICAgICpwUHJveHlJbmZvID0gKnBQcm94eUZpbGVMaXN0OwogICAgICBUUkFDRSgiZm91bmQ6IFByb3h5SW5mbyAlcCBJbmRleCAlZFxuIiwgKnBQcm94eUluZm8sICpwSW5kZXgpOwogICAgICByZXR1cm4gVFJVRTsKICAgIH0KICAgIHBQcm94eUZpbGVMaXN0Kys7CiAgfQogIFRSQUNFKCJub3QgZm91bmRcbiIpOwogIHJldHVybiBGQUxTRTsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIENTdGRQU0ZhY3RvcnlfUXVlcnlJbnRlcmZhY2UoTFBQU0ZBQ1RPUllCVUZGRVIgaWZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUkVGSUlEIHJpaWQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBWT0lEICpvYmopCnsKICBDU3RkUFNGYWN0b3J5QnVmZmVyICpUaGlzID0gKENTdGRQU0ZhY3RvcnlCdWZmZXIgKilpZmFjZTsKICBUUkFDRSgiKCVwKS0+UXVlcnlJbnRlcmZhY2UoJXMsJXApXG4iLGlmYWNlLGRlYnVnc3RyX2d1aWQocmlpZCksb2JqKTsKICBpZiAoSXNFcXVhbEdVSUQoJklJRF9JVW5rbm93bixyaWlkKSB8fAogICAgICBJc0VxdWFsR1VJRCgmSUlEX0lQU0ZhY3RvcnlCdWZmZXIscmlpZCkpIHsKICAgICpvYmogPSBUaGlzOwogICAgVGhpcy0+UmVmQ291bnQrKzsKICAgIHJldHVybiBTX09LOwogIH0KICByZXR1cm4gRV9OT0lOVEVSRkFDRTsKfQoKc3RhdGljIFVMT05HIFdJTkFQSSBDU3RkUFNGYWN0b3J5X0FkZFJlZihMUFBTRkFDVE9SWUJVRkZFUiBpZmFjZSkKewogIENTdGRQU0ZhY3RvcnlCdWZmZXIgKlRoaXMgPSAoQ1N0ZFBTRmFjdG9yeUJ1ZmZlciAqKWlmYWNlOwogIFRSQUNFKCIoJXApLT5BZGRSZWYoKVxuIixpZmFjZSk7CiAgcmV0dXJuICsrKFRoaXMtPlJlZkNvdW50KTsKfQoKc3RhdGljIFVMT05HIFdJTkFQSSBDU3RkUFNGYWN0b3J5X1JlbGVhc2UoTFBQU0ZBQ1RPUllCVUZGRVIgaWZhY2UpCnsKICBDU3RkUFNGYWN0b3J5QnVmZmVyICpUaGlzID0gKENTdGRQU0ZhY3RvcnlCdWZmZXIgKilpZmFjZTsKICBUUkFDRSgiKCVwKS0+UmVsZWFzZSgpXG4iLGlmYWNlKTsKICByZXR1cm4gLS0oVGhpcy0+UmVmQ291bnQpOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgQ1N0ZFBTRmFjdG9yeV9DcmVhdGVQcm94eShMUFBTRkFDVE9SWUJVRkZFUiBpZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUFVOS05PV04gcFVua091dGVyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFJFRklJRCByaWlkLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQUlBDUFJPWFlCVUZGRVIgKnBwUHJveHksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBWT0lEICpwcHYpCnsKICBDU3RkUFNGYWN0b3J5QnVmZmVyICpUaGlzID0gKENTdGRQU0ZhY3RvcnlCdWZmZXIgKilpZmFjZTsKICBjb25zdCBQcm94eUZpbGVJbmZvICpQcm94eUluZm87CiAgaW50IEluZGV4OwogIFRSQUNFKCIoJXApLT5DcmVhdGVQcm94eSglcCwlcywlcCwlcClcbiIsaWZhY2UscFVua091dGVyLAogICAgICAgZGVidWdzdHJfZ3VpZChyaWlkKSxwcFByb3h5LHBwdik7CiAgaWYgKCFGaW5kUHJveHlJbmZvKFRoaXMtPnBQcm94eUZpbGVMaXN0LHJpaWQsJlByb3h5SW5mbywmSW5kZXgpKQogICAgcmV0dXJuIEVfTk9JTlRFUkZBQ0U7CiAgcmV0dXJuIFN0ZFByb3h5X0NvbnN0cnVjdChyaWlkLCBwVW5rT3V0ZXIsIFByb3h5SW5mbywgSW5kZXgsIGlmYWNlLCBwcFByb3h5LCBwcHYpOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgQ1N0ZFBTRmFjdG9yeV9DcmVhdGVTdHViKExQUFNGQUNUT1JZQlVGRkVSIGlmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUkVGSUlEIHJpaWQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUFVOS05PV04gcFVua1NlcnZlciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQUlBDU1RVQkJVRkZFUiAqcHBTdHViKQp7CiAgQ1N0ZFBTRmFjdG9yeUJ1ZmZlciAqVGhpcyA9IChDU3RkUFNGYWN0b3J5QnVmZmVyICopaWZhY2U7CiAgY29uc3QgUHJveHlGaWxlSW5mbyAqUHJveHlJbmZvOwogIGludCBJbmRleDsKICBUUkFDRSgiKCVwKS0+Q3JlYXRlU3R1YiglcywlcCwlcClcbiIsaWZhY2UsZGVidWdzdHJfZ3VpZChyaWlkKSwKICAgICAgIHBVbmtTZXJ2ZXIscHBTdHViKTsKICBpZiAoIUZpbmRQcm94eUluZm8oVGhpcy0+cFByb3h5RmlsZUxpc3QscmlpZCwmUHJveHlJbmZvLCZJbmRleCkpCiAgICByZXR1cm4gRV9OT0lOVEVSRkFDRTsKICByZXR1cm4gQ1N0ZFN0dWJCdWZmZXJfQ29uc3RydWN0KHJpaWQsIHBVbmtTZXJ2ZXIsIFByb3h5SW5mby0+cE5hbWVzQXJyYXlbSW5kZXhdLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUHJveHlJbmZvLT5wU3R1YlZ0YmxMaXN0W0luZGV4XSwgaWZhY2UsIHBwU3R1Yik7Cn0KCnN0YXRpYyBjb25zdCBJUFNGYWN0b3J5QnVmZmVyVnRibCBDU3RkUFNGYWN0b3J5X1Z0YmwgPQp7CiAgQ1N0ZFBTRmFjdG9yeV9RdWVyeUludGVyZmFjZSwKICBDU3RkUFNGYWN0b3J5X0FkZFJlZiwKICBDU3RkUFNGYWN0b3J5X1JlbGVhc2UsCiAgQ1N0ZFBTRmFjdG9yeV9DcmVhdGVQcm94eSwKICBDU3RkUFNGYWN0b3J5X0NyZWF0ZVN0dWIKfTsKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgTmRyRGxsR2V0Q2xhc3NPYmplY3QgW1JQQ1JUNC5AXQogKi8KSFJFU1VMVCBXSU5BUEkgTmRyRGxsR2V0Q2xhc3NPYmplY3QoUkVGQ0xTSUQgcmNsc2lkLCBSRUZJSUQgaWlkLCBMUFZPSUQgKnBwdiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBQcm94eUZpbGVJbmZvICoqcFByb3h5RmlsZUxpc3QsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgQ0xTSUQgKnBjbHNpZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBDU3RkUFNGYWN0b3J5QnVmZmVyICpwUFNGYWN0b3J5QnVmZmVyKQp7CiAgVFJBQ0UoIiglcywgJXMsICVwLCAlcCwgJXMsICVwKVxuIiwgZGVidWdzdHJfZ3VpZChyY2xzaWQpLAogICAgZGVidWdzdHJfZ3VpZChpaWQpLCBwcHYsIHBQcm94eUZpbGVMaXN0LCBkZWJ1Z3N0cl9ndWlkKHBjbHNpZCksCiAgICBwUFNGYWN0b3J5QnVmZmVyKTsKCiAgKnBwdiA9IE5VTEw7CiAgaWYgKCFwUFNGYWN0b3J5QnVmZmVyLT5scFZ0YmwpIHsKICAgIGNvbnN0IFByb3h5RmlsZUluZm8gKipwUHJveHlGaWxlTGlzdDI7CiAgICBwUFNGYWN0b3J5QnVmZmVyLT5scFZ0YmwgPSAmQ1N0ZFBTRmFjdG9yeV9WdGJsOwogICAgcFBTRmFjdG9yeUJ1ZmZlci0+UmVmQ291bnQgPSAwOwogICAgcFBTRmFjdG9yeUJ1ZmZlci0+cFByb3h5RmlsZUxpc3QgPSBwUHJveHlGaWxlTGlzdDsKICAgIGZvciAocFByb3h5RmlsZUxpc3QyID0gcFByb3h5RmlsZUxpc3Q7ICpwUHJveHlGaWxlTGlzdDI7IHBQcm94eUZpbGVMaXN0MisrKSB7CiAgICAgIGludCBpOwogICAgICBmb3IgKGkgPSAwOyBpIDwgKCpwUHJveHlGaWxlTGlzdDIpLT5UYWJsZVNpemU7IGkrKykgewogICAgICAgIC8qIEZJWE1FOiBpIHRoaW5rIHRoYXQgZGlmZmVyZW50IHZ0YWJsZXMgc2hvdWxkIGJlIGNvcGllZCBmb3IKICAgICAgICAgKiBhc3luYyBpbnRlcmZhY2VzICovCiAgICAgICAgdm9pZCAqIGNvbnN0ICpwU3JjUnBjU3R1YlZ0YmwgPSAodm9pZCAqIGNvbnN0ICopJkNTdGRTdHViQnVmZmVyX1Z0Ymw7CiAgICAgICAgdm9pZCAqKnBScGNTdHViVnRibCA9ICh2b2lkICoqKSYoKnBQcm94eUZpbGVMaXN0MiktPnBTdHViVnRibExpc3RbaV0tPlZ0Ymw7CiAgICAgICAgaW50IGo7CgogICAgICAgIGZvciAoaiA9IDA7IGogPCBzaXplb2YoSVJwY1N0dWJCdWZmZXJWdGJsKS9zaXplb2Yodm9pZCAqKTsgaisrKQogICAgICAgICAgaWYgKCFwUnBjU3R1YlZ0Ymxbal0pCiAgICAgICAgICAgIHBScGNTdHViVnRibFtqXSA9IHBTcmNScGNTdHViVnRibFtqXTsKICAgICAgfQogICAgfQogIH0KICBpZiAoSXNFcXVhbEdVSUQocmNsc2lkLCBwY2xzaWQpKQogICAgcmV0dXJuIElQU0ZhY3RvcnlCdWZmZXJfUXVlcnlJbnRlcmZhY2UoKExQUFNGQUNUT1JZQlVGRkVSKXBQU0ZhY3RvcnlCdWZmZXIsIGlpZCwgcHB2KTsKICBlbHNlIHsKICAgIGNvbnN0IFByb3h5RmlsZUluZm8gKmluZm87CiAgICBpbnQgaW5kZXg7CiAgICAvKiBvdGhlcndpc2UsIHRoZSBkbGwgbWF5IGJlIHVzaW5nIHRoZSBpaWQgYXMgdGhlIGNsc2lkLCBzbwogICAgICogc2VhcmNoIGZvciBpdCBpbiB0aGUgcHJveHkgZmlsZSBsaXN0ICovCiAgICBpZiAoRmluZFByb3h5SW5mbyhwUHJveHlGaWxlTGlzdCwgcmNsc2lkLCAmaW5mbywgJmluZGV4KSkKICAgICAgcmV0dXJuIElQU0ZhY3RvcnlCdWZmZXJfUXVlcnlJbnRlcmZhY2UoKExQUFNGQUNUT1JZQlVGRkVSKXBQU0ZhY3RvcnlCdWZmZXIsIGlpZCwgcHB2KTsKCiAgICBXQVJOKCJjbGFzcyAlcyBub3QgYXZhaWxhYmxlXG4iLCBkZWJ1Z3N0cl9ndWlkKHJjbHNpZCkpOwogICAgcmV0dXJuIENMQVNTX0VfQ0xBU1NOT1RBVkFJTEFCTEU7CiAgfQp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgIE5kckRsbENhblVubG9hZE5vdyBbUlBDUlQ0LkBdCiAqLwpIUkVTVUxUIFdJTkFQSSBOZHJEbGxDYW5VbmxvYWROb3coQ1N0ZFBTRmFjdG9yeUJ1ZmZlciAqcFBTRmFjdG9yeUJ1ZmZlcikKewogIHJldHVybiAhKHBQU0ZhY3RvcnlCdWZmZXItPlJlZkNvdW50KTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICBOZHJEbGxSZWdpc3RlclByb3h5IFtSUENSVDQuQF0KICovCkhSRVNVTFQgV0lOQVBJIE5kckRsbFJlZ2lzdGVyUHJveHkoSE1PRFVMRSBoRGxsLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgUHJveHlGaWxlSW5mbyAqKnBQcm94eUZpbGVMaXN0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgQ0xTSUQgKnBjbHNpZCkKewogIExQU1RSIGNsc2lkOwogIGNoYXIga2V5bmFtZVsxMjBdLCBtb2R1bGVbTUFYX1BBVEhdOwogIEhLRVkga2V5LCBzdWJrZXk7CiAgRFdPUkQgbGVuOwoKICBUUkFDRSgiKCVwLCVwLCVzKVxuIiwgaERsbCwgcFByb3h5RmlsZUxpc3QsIGRlYnVnc3RyX2d1aWQocGNsc2lkKSk7CiAgVXVpZFRvU3RyaW5nQSgoVVVJRCopcGNsc2lkLCAodW5zaWduZWQgY2hhcioqKSZjbHNpZCk7CgogIC8qIHJlZ2lzdGVyIGludGVyZmFjZXMgdG8gcG9pbnQgdG8gY2xzaWQgKi8KICB3aGlsZSAoKnBQcm94eUZpbGVMaXN0KSB7CiAgICB1bnNpZ25lZCB1OwogICAgZm9yICh1PTA7IHU8KCpwUHJveHlGaWxlTGlzdCktPlRhYmxlU2l6ZTsgdSsrKSB7CiAgICAgIENJbnRlcmZhY2VTdHViVnRibCAqcHJveHkgPSAoKnBQcm94eUZpbGVMaXN0KS0+cFN0dWJWdGJsTGlzdFt1XTsKICAgICAgUENJbnRlcmZhY2VOYW1lIG5hbWUgPSAoKnBQcm94eUZpbGVMaXN0KS0+cE5hbWVzQXJyYXlbdV07CiAgICAgIExQU1RSIGlpZDsKCiAgICAgIFRSQUNFKCJyZWdpc3RlcmluZyAlcyAlcyA9PiAlc1xuIiwgbmFtZSwgZGVidWdzdHJfZ3VpZChwcm94eS0+aGVhZGVyLnBpaWQpLCBjbHNpZCk7CgogICAgICBVdWlkVG9TdHJpbmdBKChVVUlEKilwcm94eS0+aGVhZGVyLnBpaWQsICh1bnNpZ25lZCBjaGFyKiopJmlpZCk7CiAgICAgIHNucHJpbnRmKGtleW5hbWUsIHNpemVvZihrZXluYW1lKSwgIkludGVyZmFjZVxceyVzfSIsIGlpZCk7CiAgICAgIFJwY1N0cmluZ0ZyZWVBKCh1bnNpZ25lZCBjaGFyKiopJmlpZCk7CiAgICAgIGlmIChSZWdDcmVhdGVLZXlFeEEoSEtFWV9DTEFTU0VTX1JPT1QsIGtleW5hbWUsIDAsIE5VTEwsIDAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgS0VZX1dSSVRFLCBOVUxMLCAma2V5LCBOVUxMKSA9PSBFUlJPUl9TVUNDRVNTKSB7CiAgICAgICAgaWYgKG5hbWUpCiAgICAgICAgICBSZWdTZXRWYWx1ZUV4QShrZXksIE5VTEwsIDAsIFJFR19TWiwgKExQQllURSluYW1lLCBzdHJsZW4obmFtZSkpOwogICAgICAgIGlmIChSZWdDcmVhdGVLZXlFeEEoa2V5LCAiUHJveHlTdHViQ2xzaWQzMiIsIDAsIE5VTEwsIDAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBLRVlfV1JJVEUsIE5VTEwsICZzdWJrZXksIE5VTEwpID09IEVSUk9SX1NVQ0NFU1MpIHsKICAgICAgICAgIHNucHJpbnRmKG1vZHVsZSwgc2l6ZW9mKG1vZHVsZSksICJ7JXN9IiwgY2xzaWQpOwogICAgICAgICAgUmVnU2V0VmFsdWVFeEEoc3Via2V5LCBOVUxMLCAwLCBSRUdfU1osIChMUEJZVEUpbW9kdWxlLCBzdHJsZW4obW9kdWxlKSk7CiAgICAgICAgICBSZWdDbG9zZUtleShzdWJrZXkpOwogICAgICAgIH0KICAgICAgICBSZWdDbG9zZUtleShrZXkpOwogICAgICB9CiAgICB9CiAgICBwUHJveHlGaWxlTGlzdCsrOwogIH0KCiAgLyogcmVnaXN0ZXIgY2xzaWQgdG8gcG9pbnQgdG8gbW9kdWxlICovCiAgc25wcmludGYoa2V5bmFtZSwgc2l6ZW9mKGtleW5hbWUpLCAiQ0xTSURcXHslc30iLCBjbHNpZCk7CiAgbGVuID0gR2V0TW9kdWxlRmlsZU5hbWVBKGhEbGwsIG1vZHVsZSwgc2l6ZW9mKG1vZHVsZSkpOwogIGlmIChsZW4gJiYgbGVuIDwgc2l6ZW9mKG1vZHVsZSkpIHsKICAgIFRSQUNFKCJyZWdpc3RlcmluZyBDTFNJRCAlcyA9PiAlc1xuIiwgY2xzaWQsIG1vZHVsZSk7CiAgICBpZiAoUmVnQ3JlYXRlS2V5RXhBKEhLRVlfQ0xBU1NFU19ST09ULCBrZXluYW1lLCAwLCBOVUxMLCAwLAogICAgICAgICAgICAgICAgICAgICAgICBLRVlfV1JJVEUsIE5VTEwsICZrZXksIE5VTEwpID09IEVSUk9SX1NVQ0NFU1MpIHsKICAgICAgaWYgKFJlZ0NyZWF0ZUtleUV4QShrZXksICJJblByb2NTZXJ2ZXIzMiIsIDAsIE5VTEwsIDAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgS0VZX1dSSVRFLCBOVUxMLCAmc3Via2V5LCBOVUxMKSA9PSBFUlJPUl9TVUNDRVNTKSB7CiAgICAgICAgUmVnU2V0VmFsdWVFeEEoc3Via2V5LCBOVUxMLCAwLCBSRUdfU1osIChMUEJZVEUpbW9kdWxlLCBzdHJsZW4obW9kdWxlKSk7CiAgICAgICAgUmVnQ2xvc2VLZXkoc3Via2V5KTsKICAgICAgfQogICAgICBSZWdDbG9zZUtleShrZXkpOwogICAgfQogIH0KCiAgLyogZG9uZSAqLwogIFJwY1N0cmluZ0ZyZWVBKCh1bnNpZ25lZCBjaGFyKiopJmNsc2lkKTsKICByZXR1cm4gU19PSzsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICBOZHJEbGxVbnJlZ2lzdGVyUHJveHkgW1JQQ1JUNC5AXQogKi8KSFJFU1VMVCBXSU5BUEkgTmRyRGxsVW5yZWdpc3RlclByb3h5KEhNT0RVTEUgaERsbCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgUHJveHlGaWxlSW5mbyAqKnBQcm94eUZpbGVMaXN0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBDTFNJRCAqcGNsc2lkKQp7CiAgTFBTVFIgY2xzaWQ7CiAgY2hhciBrZXluYW1lWzEyMF0sIG1vZHVsZVtNQVhfUEFUSF07CiAgRFdPUkQgbGVuOwoKICBUUkFDRSgiKCVwLCVwLCVzKVxuIiwgaERsbCwgcFByb3h5RmlsZUxpc3QsIGRlYnVnc3RyX2d1aWQocGNsc2lkKSk7CiAgVXVpZFRvU3RyaW5nQSgoVVVJRCopcGNsc2lkLCAodW5zaWduZWQgY2hhcioqKSZjbHNpZCk7CgogIC8qIHVucmVnaXN0ZXIgaW50ZXJmYWNlcyAqLwogIHdoaWxlICgqcFByb3h5RmlsZUxpc3QpIHsKICAgIHVuc2lnbmVkIHU7CiAgICBmb3IgKHU9MDsgdTwoKnBQcm94eUZpbGVMaXN0KS0+VGFibGVTaXplOyB1KyspIHsKICAgICAgQ0ludGVyZmFjZVN0dWJWdGJsICpwcm94eSA9ICgqcFByb3h5RmlsZUxpc3QpLT5wU3R1YlZ0YmxMaXN0W3VdOwogICAgICBQQ0ludGVyZmFjZU5hbWUgbmFtZSA9ICgqcFByb3h5RmlsZUxpc3QpLT5wTmFtZXNBcnJheVt1XTsKICAgICAgTFBTVFIgaWlkOwoKICAgICAgVFJBQ0UoInVucmVnaXN0ZXJpbmcgJXMgJXMgPD0gJXNcbiIsIG5hbWUsIGRlYnVnc3RyX2d1aWQocHJveHktPmhlYWRlci5waWlkKSwgY2xzaWQpOwoKICAgICAgVXVpZFRvU3RyaW5nQSgoVVVJRCopcHJveHktPmhlYWRlci5waWlkLCAodW5zaWduZWQgY2hhcioqKSZpaWQpOwogICAgICBzbnByaW50ZihrZXluYW1lLCBzaXplb2Yoa2V5bmFtZSksICJJbnRlcmZhY2VcXHslc30iLCBpaWQpOwogICAgICBScGNTdHJpbmdGcmVlQSgodW5zaWduZWQgY2hhcioqKSZpaWQpOwogICAgICBSZWdEZWxldGVLZXlBKEhLRVlfQ0xBU1NFU19ST09ULCBrZXluYW1lKTsKICAgIH0KICAgIHBQcm94eUZpbGVMaXN0Kys7CiAgfQoKICAvKiB1bnJlZ2lzdGVyIGNsc2lkICovCiAgc25wcmludGYoa2V5bmFtZSwgc2l6ZW9mKGtleW5hbWUpLCAiQ0xTSURcXHslc30iLCBjbHNpZCk7CiAgbGVuID0gR2V0TW9kdWxlRmlsZU5hbWVBKGhEbGwsIG1vZHVsZSwgc2l6ZW9mKG1vZHVsZSkpOwogIGlmIChsZW4gJiYgbGVuIDwgc2l6ZW9mKG1vZHVsZSkpIHsKICAgIFRSQUNFKCJ1bnJlZ2lzdGVyaW5nIENMU0lEICVzIDw9ICVzXG4iLCBjbHNpZCwgbW9kdWxlKTsKICAgIFJlZ0RlbGV0ZUtleUEoSEtFWV9DTEFTU0VTX1JPT1QsIGtleW5hbWUpOwogIH0KCiAgLyogZG9uZSAqLwogIFJwY1N0cmluZ0ZyZWVBKCh1bnNpZ25lZCBjaGFyKiopJmNsc2lkKTsKICByZXR1cm4gU19PSzsKfQo=