LyoKICoJUlBDIE1hbmFnZXIKICoKICogQ29weXJpZ2h0IDIwMDEgIE92ZSBL5XZlbiwgVHJhbnNHYW1pbmcgVGVjaG5vbG9naWVzCiAqIENvcHlyaWdodCAyMDAyICBNYXJjdXMgTWVpc3NuZXIKICogQ29weXJpZ2h0IDIwMDUgIE1pa2UgSGVhcm4sIFJvYiBTaGVhcm1hbiBmb3IgQ29kZVdlYXZlcnMKICoKICogVGhpcyBsaWJyYXJ5IGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vcgogKiBtb2RpZnkgaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljCiAqIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlcgogKiB2ZXJzaW9uIDIuMSBvZiB0aGUgTGljZW5zZSwgb3IgKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi4KICoKICogVGhpcyBsaWJyYXJ5IGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsCiAqIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mCiAqIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VCiAqIExlc3NlciBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMKICogTGljZW5zZSBhbG9uZyB3aXRoIHRoaXMgbGlicmFyeTsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZQogKiBGb3VuZGF0aW9uLCBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSwgVVNBCiAqLwoKI2luY2x1ZGUgImNvbmZpZy5oIgojaW5jbHVkZSAid2luZS9wb3J0LmgiCgojaW5jbHVkZSA8c3RkbGliLmg+CiNpbmNsdWRlIDxzdGRhcmcuaD4KI2luY2x1ZGUgPHN0ZGlvLmg+CiNpbmNsdWRlIDxzdHJpbmcuaD4KI2luY2x1ZGUgPGFzc2VydC5oPgoKI2RlZmluZSBDT0JKTUFDUk9TCiNkZWZpbmUgTk9OQU1FTEVTU1VOSU9OCiNkZWZpbmUgTk9OQU1FTEVTU1NUUlVDVAoKI2luY2x1ZGUgIndpbmRlZi5oIgojaW5jbHVkZSAid2luYmFzZS5oIgojaW5jbHVkZSAid2ludXNlci5oIgojaW5jbHVkZSAid2luc3ZjLmgiCiNpbmNsdWRlICJvYmpiYXNlLmgiCiNpbmNsdWRlICJvbGUyLmgiCiNpbmNsdWRlICJycGMuaCIKI2luY2x1ZGUgIndpbmVycm9yLmgiCiNpbmNsdWRlICJ3aW5yZWcuaCIKI2luY2x1ZGUgInd0eXBlcy5oIgojaW5jbHVkZSAid2luZS91bmljb2RlLmgiCgojaW5jbHVkZSAiY29tcG9ial9wcml2YXRlLmgiCgojaW5jbHVkZSAid2luZS9kZWJ1Zy5oIgoKV0lORV9ERUZBVUxUX0RFQlVHX0NIQU5ORUwob2xlKTsKCnN0YXRpYyB2b2lkIF9fUlBDX1NUVUIgZGlzcGF0Y2hfcnBjKFJQQ19NRVNTQUdFICptc2cpOwoKLyogd2Ugb25seSB1c2Ugb25lIGZ1bmN0aW9uIHRvIGRpc3BhdGNoIGNhbGxzIGZvciBhbGwgbWV0aG9kcyAtIHdlIHVzZSB0aGUKICogUlBDX0lGX09MRSBmbGFnIHRvIHRlbGwgdGhlIFJQQyBydW50aW1lIHRoYXQgdGhpcyBpcyB0aGUgY2FzZSAqLwpzdGF0aWMgUlBDX0RJU1BBVENIX0ZVTkNUSU9OIHJwY19kaXNwYXRjaF90YWJsZVsxXSA9IHsgZGlzcGF0Y2hfcnBjIH07IC8qIChSTykgKi8Kc3RhdGljIFJQQ19ESVNQQVRDSF9UQUJMRSBycGNfZGlzcGF0Y2ggPSB7IDEsIHJwY19kaXNwYXRjaF90YWJsZSB9OyAvKiAoUk8pICovCgpzdGF0aWMgc3RydWN0IGxpc3QgcmVnaXN0ZXJlZF9pbnRlcmZhY2VzID0gTElTVF9JTklUKHJlZ2lzdGVyZWRfaW50ZXJmYWNlcyk7IC8qIChDUyBjc1JlZ0lmKSAqLwpzdGF0aWMgQ1JJVElDQUxfU0VDVElPTiBjc1JlZ0lmOwpzdGF0aWMgQ1JJVElDQUxfU0VDVElPTl9ERUJVRyBjc1JlZ0lmX2RlYnVnID0KewogICAgMCwgMCwgJmNzUmVnSWYsCiAgICB7ICZjc1JlZ0lmX2RlYnVnLlByb2Nlc3NMb2Nrc0xpc3QsICZjc1JlZ0lmX2RlYnVnLlByb2Nlc3NMb2Nrc0xpc3QgfSwKICAgICAgMCwgMCwgeyAoRFdPUkRfUFRSKShfX0ZJTEVfXyAiOiBkY29tIHJlZ2lzdGVyZWQgc2VydmVyIGludGVyZmFjZXMiKSB9Cn07CnN0YXRpYyBDUklUSUNBTF9TRUNUSU9OIGNzUmVnSWYgPSB7ICZjc1JlZ0lmX2RlYnVnLCAtMSwgMCwgMCwgMCwgMCB9OwoKc3RhdGljIFdDSEFSIHdzelJwY1RyYW5zcG9ydFtdID0geyduJywnYycsJ2EnLCdsJywncicsJ3AnLCdjJywwfTsKCgpzdHJ1Y3QgcmVnaXN0ZXJlZF9pZgp7CiAgICBzdHJ1Y3QgbGlzdCBlbnRyeTsKICAgIERXT1JEIHJlZnM7IC8qIHJlZiBjb3VudCAqLwogICAgUlBDX1NFUlZFUl9JTlRFUkZBQ0UgSWY7IC8qIGludGVyZmFjZSByZWdpc3RlcmVkIHdpdGggdGhlIFJQQyBydW50aW1lICovCn07CgovKiBnZXQgdGhlIHBpcGUgZW5kcG9pbnQgc3BlY2lmaWVkIG9mIHRoZSBzcGVjaWZpZWQgYXBhcnRtZW50ICovCnN0YXRpYyBpbmxpbmUgdm9pZCBnZXRfcnBjX2VuZHBvaW50KExQV1NUUiBlbmRwb2ludCwgY29uc3QgT1hJRCAqb3hpZCkKewogICAgLyogRklYTUU6IHNob3VsZCBnZXQgZW5kcG9pbnQgZnJvbSBycGNzcyAqLwogICAgc3RhdGljIGNvbnN0IFdDSEFSIHdzekVuZHBvaW50Rm9ybWF0W10gPSB7J1xcJywncCcsJ2knLCdwJywnZScsJ1xcJywnTycsJ0wnLCdFJywnXycsJyUnLCcwJywnOCcsJ2wnLCd4JywnJScsJzAnLCc4JywnbCcsJ3gnLDB9OwogICAgd3NwcmludGZXKGVuZHBvaW50LCB3c3pFbmRwb2ludEZvcm1hdCwgKERXT1JEKSgqb3hpZCA+PiAzMiksKERXT1JEKSpveGlkKTsKfQoKdHlwZWRlZiBzdHJ1Y3QKewogICAgY29uc3QgSVJwY0NoYW5uZWxCdWZmZXJWdGJsICpscFZ0Ymw7CiAgICBMT05HICAgICAgICAgICAgICAgICAgcmVmczsKfSBScGNDaGFubmVsQnVmZmVyOwoKdHlwZWRlZiBzdHJ1Y3QKewogICAgUnBjQ2hhbm5lbEJ1ZmZlciAgICAgICBzdXBlcjsgLyogc3VwZXJjbGFzcyAqLwoKICAgIFJQQ19CSU5ESU5HX0hBTkRMRSAgICAgYmluZDsgLyogaGFuZGxlIHRvIHRoZSByZW1vdGUgc2VydmVyICovCiAgICBPWElEICAgICAgICAgICAgICAgICAgIG94aWQ7IC8qIGFwYXJ0bWVudCBpbiB3aGljaCB0aGUgY2hhbm5lbCBpcyB2YWxpZCAqLwogICAgRFdPUkQgICAgICAgICAgICAgICAgICBkZXN0X2NvbnRleHQ7IC8qIHJldHVybmVkIGZyb20gR2V0RGVzdEN0eCAqLwogICAgTFBWT0lEICAgICAgICAgICAgICAgICBkZXN0X2NvbnRleHRfZGF0YTsgLyogcmV0dXJuZWQgZnJvbSBHZXREZXN0Q3R4ICovCiAgICBIQU5ETEUgICAgICAgICAgICAgICAgIGV2ZW50OyAvKiBjYWNoZWQgZXZlbnQgaGFuZGxlICovCn0gQ2xpZW50UnBjQ2hhbm5lbEJ1ZmZlcjsKCnN0cnVjdCBkaXNwYXRjaF9wYXJhbXMKewogICAgUlBDT0xFTUVTU0FHRSAgICAgKm1zZzsgLyogbWVzc2FnZSAqLwogICAgSVJwY1N0dWJCdWZmZXIgICAgKnN0dWI7IC8qIHN0dWIgYnVmZmVyLCBpZiBhcHBsaWNhYmxlICovCiAgICBJUnBjQ2hhbm5lbEJ1ZmZlciAqY2hhbjsgLyogc2VydmVyIGNoYW5uZWwgYnVmZmVyLCBpZiBhcHBsaWNhYmxlICovCiAgICBIQU5ETEUgICAgICAgICAgICAgaGFuZGxlOyAvKiBoYW5kbGUgdGhhdCB3aWxsIGJlY29tZSBzaWduYWxlZCB3aGVuIGNhbGwgZmluaXNoZXMgKi8KICAgIFJQQ19TVEFUVVMgICAgICAgICBzdGF0dXM7IC8qIHN0YXR1cyAob3V0KSAqLwogICAgSFJFU1VMVCAgICAgICAgICAgIGhyOyAvKiBocmVzdWx0IChvdXQpICovCn07CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgUnBjQ2hhbm5lbEJ1ZmZlcl9RdWVyeUludGVyZmFjZShMUFJQQ0NIQU5ORUxCVUZGRVIgaWZhY2UsIFJFRklJRCByaWlkLCBMUFZPSUQgKnBwdikKewogICAgKnBwdiA9IE5VTEw7CiAgICBpZiAoSXNFcXVhbElJRChyaWlkLCZJSURfSVJwY0NoYW5uZWxCdWZmZXIpIHx8IElzRXF1YWxJSUQocmlpZCwmSUlEX0lVbmtub3duKSkKICAgIHsKICAgICAgICAqcHB2ID0gKExQVk9JRClpZmFjZTsKICAgICAgICBJVW5rbm93bl9BZGRSZWYoaWZhY2UpOwogICAgICAgIHJldHVybiBTX09LOwogICAgfQogICAgcmV0dXJuIEVfTk9JTlRFUkZBQ0U7Cn0KCnN0YXRpYyBVTE9ORyBXSU5BUEkgUnBjQ2hhbm5lbEJ1ZmZlcl9BZGRSZWYoTFBSUENDSEFOTkVMQlVGRkVSIGlmYWNlKQp7CiAgICBScGNDaGFubmVsQnVmZmVyICpUaGlzID0gKFJwY0NoYW5uZWxCdWZmZXIgKilpZmFjZTsKICAgIHJldHVybiBJbnRlcmxvY2tlZEluY3JlbWVudCgmVGhpcy0+cmVmcyk7Cn0KCnN0YXRpYyBVTE9ORyBXSU5BUEkgU2VydmVyUnBjQ2hhbm5lbEJ1ZmZlcl9SZWxlYXNlKExQUlBDQ0hBTk5FTEJVRkZFUiBpZmFjZSkKewogICAgUnBjQ2hhbm5lbEJ1ZmZlciAqVGhpcyA9IChScGNDaGFubmVsQnVmZmVyICopaWZhY2U7CiAgICBVTE9ORyByZWY7CgogICAgcmVmID0gSW50ZXJsb2NrZWREZWNyZW1lbnQoJlRoaXMtPnJlZnMpOwogICAgaWYgKHJlZikKICAgICAgICByZXR1cm4gcmVmOwoKICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIFRoaXMpOwogICAgcmV0dXJuIDA7Cn0KCnN0YXRpYyBVTE9ORyBXSU5BUEkgQ2xpZW50UnBjQ2hhbm5lbEJ1ZmZlcl9SZWxlYXNlKExQUlBDQ0hBTk5FTEJVRkZFUiBpZmFjZSkKewogICAgQ2xpZW50UnBjQ2hhbm5lbEJ1ZmZlciAqVGhpcyA9IChDbGllbnRScGNDaGFubmVsQnVmZmVyICopaWZhY2U7CiAgICBVTE9ORyByZWY7CgogICAgcmVmID0gSW50ZXJsb2NrZWREZWNyZW1lbnQoJlRoaXMtPnN1cGVyLnJlZnMpOwogICAgaWYgKHJlZikKICAgICAgICByZXR1cm4gcmVmOwoKICAgIGlmIChUaGlzLT5ldmVudCkgQ2xvc2VIYW5kbGUoVGhpcy0+ZXZlbnQpOwogICAgUnBjQmluZGluZ0ZyZWUoJlRoaXMtPmJpbmQpOwogICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgVGhpcyk7CiAgICByZXR1cm4gMDsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIFNlcnZlclJwY0NoYW5uZWxCdWZmZXJfR2V0QnVmZmVyKExQUlBDQ0hBTk5FTEJVRkZFUiBpZmFjZSwgUlBDT0xFTUVTU0FHRSogb2xlbXNnLCBSRUZJSUQgcmlpZCkKewogICAgUnBjQ2hhbm5lbEJ1ZmZlciAqVGhpcyA9IChScGNDaGFubmVsQnVmZmVyICopaWZhY2U7CiAgICBSUENfTUVTU0FHRSAqbXNnID0gKFJQQ19NRVNTQUdFICopb2xlbXNnOwogICAgUlBDX1NUQVRVUyBzdGF0dXM7CgogICAgVFJBQ0UoIiglcCktPiglcCwlcylcbiIsIFRoaXMsIG9sZW1zZywgZGVidWdzdHJfZ3VpZChyaWlkKSk7CgogICAgc3RhdHVzID0gSV9ScGNHZXRCdWZmZXIobXNnKTsKCiAgICBUUkFDRSgiLS0gJWxkXG4iLCBzdGF0dXMpOwoKICAgIHJldHVybiBIUkVTVUxUX0ZST01fV0lOMzIoc3RhdHVzKTsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIENsaWVudFJwY0NoYW5uZWxCdWZmZXJfR2V0QnVmZmVyKExQUlBDQ0hBTk5FTEJVRkZFUiBpZmFjZSwgUlBDT0xFTUVTU0FHRSogb2xlbXNnLCBSRUZJSUQgcmlpZCkKewogICAgQ2xpZW50UnBjQ2hhbm5lbEJ1ZmZlciAqVGhpcyA9IChDbGllbnRScGNDaGFubmVsQnVmZmVyICopaWZhY2U7CiAgICBSUENfTUVTU0FHRSAqbXNnID0gKFJQQ19NRVNTQUdFICopb2xlbXNnOwogICAgUlBDX0NMSUVOVF9JTlRFUkZBQ0UgKmNpZjsKICAgIFJQQ19TVEFUVVMgc3RhdHVzOwoKICAgIFRSQUNFKCIoJXApLT4oJXAsJXMpXG4iLCBUaGlzLCBvbGVtc2csIGRlYnVnc3RyX2d1aWQocmlpZCkpOwoKICAgIGNpZiA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCBIRUFQX1pFUk9fTUVNT1JZLCBzaXplb2YoUlBDX0NMSUVOVF9JTlRFUkZBQ0UpKTsKICAgIGlmICghY2lmKQogICAgICAgIHJldHVybiBFX09VVE9GTUVNT1JZOwoKICAgIGNpZi0+TGVuZ3RoID0gc2l6ZW9mKFJQQ19DTElFTlRfSU5URVJGQUNFKTsKICAgIC8qIFJQQyBpbnRlcmZhY2UgSUQgPSBDT00gaW50ZXJmYWNlIElEICovCiAgICBjaWYtPkludGVyZmFjZUlkLlN5bnRheEdVSUQgPSAqcmlpZDsKICAgIC8qIENPTSBvYmplY3RzIGFsd2F5cyBoYXZlIGEgdmVyc2lvbiBvZiAwLjAgKi8KICAgIGNpZi0+SW50ZXJmYWNlSWQuU3ludGF4VmVyc2lvbi5NYWpvclZlcnNpb24gPSAwOwogICAgY2lmLT5JbnRlcmZhY2VJZC5TeW50YXhWZXJzaW9uLk1pbm9yVmVyc2lvbiA9IDA7CiAgICBtc2ctPlJwY0ludGVyZmFjZUluZm9ybWF0aW9uID0gY2lmOwogICAgbXNnLT5IYW5kbGUgPSBUaGlzLT5iaW5kOwogICAgCiAgICBzdGF0dXMgPSBJX1JwY0dldEJ1ZmZlcihtc2cpOwoKICAgIFRSQUNFKCItLSAlbGRcbiIsIHN0YXR1cyk7CgogICAgcmV0dXJuIEhSRVNVTFRfRlJPTV9XSU4zMihzdGF0dXMpOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgU2VydmVyUnBjQ2hhbm5lbEJ1ZmZlcl9TZW5kUmVjZWl2ZShMUFJQQ0NIQU5ORUxCVUZGRVIgaWZhY2UsIFJQQ09MRU1FU1NBR0UgKm9sZW1zZywgVUxPTkcgKnBzdGF0dXMpCnsKICAgIEZJWE1FKCJzdHViXG4iKTsKICAgIHJldHVybiBFX05PVElNUEw7Cn0KCnN0YXRpYyBIQU5ETEUgQ2xpZW50UnBjQ2hhbm5lbEJ1ZmZlcl9HZXRFdmVudEhhbmRsZShDbGllbnRScGNDaGFubmVsQnVmZmVyICpUaGlzKQp7CiAgICBIQU5ETEUgZXZlbnQgPSBJbnRlcmxvY2tlZEV4Y2hhbmdlUG9pbnRlcigmVGhpcy0+ZXZlbnQsIE5VTEwpOwoKICAgIC8qIE5vdGU6IG11c3QgYmUgYXV0by1yZXNldCBldmVudCBzbyB3ZSBjYW4gcmV1c2UgaXQgd2l0aG91dCBhIGNhbGwKICAgICAqIHRvIFJlc2V0RXZlbnQgKi8KICAgIGlmICghZXZlbnQpIGV2ZW50ID0gQ3JlYXRlRXZlbnRXKE5VTEwsIEZBTFNFLCBGQUxTRSwgTlVMTCk7CgogICAgcmV0dXJuIGV2ZW50Owp9CgpzdGF0aWMgdm9pZCBDbGllbnRScGNDaGFubmVsQnVmZmVyX1JlbGVhc2VFdmVudEhhbmRsZShDbGllbnRScGNDaGFubmVsQnVmZmVyICpUaGlzLCBIQU5ETEUgZXZlbnQpCnsKICAgIGlmIChJbnRlcmxvY2tlZENvbXBhcmVFeGNoYW5nZVBvaW50ZXIoJlRoaXMtPmV2ZW50LCBldmVudCwgTlVMTCkpCiAgICAgICAgLyogYWxyZWFkeSBhIGhhbmRsZSBjYWNoZWQgaW4gVGhpcyAqLwogICAgICAgIENsb3NlSGFuZGxlKGV2ZW50KTsKfQoKLyogdGhpcyB0aHJlYWQgcnVucyBhbiBvdXRnb2luZyBSUEMgKi8Kc3RhdGljIERXT1JEIFdJTkFQSSBycGNfc2VuZHJlY2VpdmVfdGhyZWFkKExQVk9JRCBwYXJhbSkKewogICAgc3RydWN0IGRpc3BhdGNoX3BhcmFtcyAqZGF0YSA9IChzdHJ1Y3QgZGlzcGF0Y2hfcGFyYW1zICopIHBhcmFtOwoKICAgIC8qIEZJWE1FOiB0cmFwIGFuZCByZXRocm93IFJQQyBleGNlcHRpb25zIGluIGFwcCB0aHJlYWQgKi8KICAgIGRhdGEtPnN0YXR1cyA9IElfUnBjU2VuZFJlY2VpdmUoKFJQQ19NRVNTQUdFICopZGF0YS0+bXNnKTsKCiAgICBUUkFDRSgiY29tcGxldGVkIHdpdGggc3RhdHVzIDB4JWx4XG4iLCBkYXRhLT5zdGF0dXMpOwoKICAgIFNldEV2ZW50KGRhdGEtPmhhbmRsZSk7CgogICAgcmV0dXJuIDA7Cn0KCnN0YXRpYyBpbmxpbmUgSFJFU1VMVCBDbGllbnRScGNDaGFubmVsQnVmZmVyX0lzQ29ycmVjdEFwYXJ0bWVudChDbGllbnRScGNDaGFubmVsQnVmZmVyICpUaGlzLCBBUEFSVE1FTlQgKmFwdCkKewogICAgT1hJRCBveGlkOwogICAgaWYgKCFhcHQpCiAgICAgICAgcmV0dXJuIFNfRkFMU0U7CiAgICBpZiAoYXBhcnRtZW50X2dldG94aWQoYXB0LCAmb3hpZCkgIT0gU19PSykKICAgICAgICByZXR1cm4gU19GQUxTRTsKICAgIGlmIChUaGlzLT5veGlkICE9IG94aWQpCiAgICAgICAgcmV0dXJuIFNfRkFMU0U7CiAgICByZXR1cm4gU19PSzsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIENsaWVudFJwY0NoYW5uZWxCdWZmZXJfU2VuZFJlY2VpdmUoTFBSUENDSEFOTkVMQlVGRkVSIGlmYWNlLCBSUENPTEVNRVNTQUdFICpvbGVtc2csIFVMT05HICpwc3RhdHVzKQp7CiAgICBDbGllbnRScGNDaGFubmVsQnVmZmVyICpUaGlzID0gKENsaWVudFJwY0NoYW5uZWxCdWZmZXIgKilpZmFjZTsKICAgIEhSRVNVTFQgaHI7CiAgICBSUENfTUVTU0FHRSAqbXNnID0gKFJQQ19NRVNTQUdFICopb2xlbXNnOwogICAgUlBDX1NUQVRVUyBzdGF0dXM7CiAgICBEV09SRCBpbmRleDsKICAgIHN0cnVjdCBkaXNwYXRjaF9wYXJhbXMgKnBhcmFtczsKICAgIEFQQVJUTUVOVCAqYXB0ID0gTlVMTDsKICAgIElQSUQgaXBpZDsKCiAgICBUUkFDRSgiKCVwKSBpTWV0aG9kPSVkXG4iLCBvbGVtc2csIG9sZW1zZy0+aU1ldGhvZCk7CgogICAgaHIgPSBDbGllbnRScGNDaGFubmVsQnVmZmVyX0lzQ29ycmVjdEFwYXJ0bWVudChUaGlzLCBDT01fQ3VycmVudEFwdCgpKTsKICAgIGlmIChociAhPSBTX09LKQogICAgewogICAgICAgIEVSUigiY2FsbGVkIGZyb20gd3JvbmcgYXBhcnRtZW50LCBzaG91bGQgaGF2ZSBiZWVuIDB4JXNcbiIsCiAgICAgICAgICAgIHdpbmVfZGJnc3RyX2xvbmdsb25nKFRoaXMtPm94aWQpKTsKICAgICAgICByZXR1cm4gUlBDX0VfV1JPTkdfVEhSRUFEOwogICAgfQoKICAgIHBhcmFtcyA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCBIRUFQX1pFUk9fTUVNT1JZLCBzaXplb2YoKnBhcmFtcykpOwogICAgaWYgKCFwYXJhbXMpIHJldHVybiBFX09VVE9GTUVNT1JZOwoKICAgIHBhcmFtcy0+bXNnID0gb2xlbXNnOwogICAgcGFyYW1zLT5zdGF0dXMgPSBSUENfU19PSzsKICAgIHBhcmFtcy0+aHIgPSBTX09LOwoKICAgIC8qIE5vdGU6IHRoaXMgaXMgYW4gb3B0aW1pemF0aW9uIGluIHRoZSBNaWNyb3NvZnQgT0xFIHJ1bnRpbWUgdGhhdCB3ZSBuZWVkCiAgICAgKiB0byBjb3B5LCBhcyBzaG93biBieSB0aGUgdGVzdF9ub19jb3VuaW5pdGlhbGl6ZV9jbGllbnQgdGVzdC4gd2l0aG91dAogICAgICogc2hvcnQtY2lyY3VpdGluZyB0aGUgUlBDIHJ1bnRpbWUgaW4gdGhlIGNhc2UgYmVsb3csIHRoZSB0ZXN0IHdpbGwKICAgICAqIGRlYWRsb2NrIG9uIHRoZSBsb2FkZXIgbG9jayBkdWUgdG8gdGhlIFJQQyBydW50aW1lIG5lZWRpbmcgdG8gY3JlYXRlCiAgICAgKiBhIHRocmVhZCB0byBwcm9jZXNzIHRoZSBSUEMgd2hlbiB0aGlzIGZ1bmN0aW9uIGlzIGNhbGxlZCBpbmRpcmVjdGx5CiAgICAgKiBmcm9tIERsbE1haW4gKi8KCiAgICBScGNCaW5kaW5nSW5xT2JqZWN0KG1zZy0+SGFuZGxlLCAmaXBpZCk7CiAgICBociA9IGlwaWRfZ2V0X2Rpc3BhdGNoX3BhcmFtcygmaXBpZCwgJmFwdCwgJnBhcmFtcy0+c3R1YiwgJnBhcmFtcy0+Y2hhbik7CiAgICBwYXJhbXMtPmhhbmRsZSA9IENsaWVudFJwY0NoYW5uZWxCdWZmZXJfR2V0RXZlbnRIYW5kbGUoVGhpcyk7CiAgICBpZiAoKGhyID09IFNfT0spICYmICFhcHQtPm11bHRpX3RocmVhZGVkKQogICAgewogICAgICAgIFRSQUNFKCJDYWxsaW5nIGFwYXJ0bWVudCB0aHJlYWQgMHglMDh4Li4uXG4iLCBhcHQtPnRpZCk7CgogICAgICAgIGlmICghUG9zdE1lc3NhZ2VXKGFwYXJ0bWVudF9nZXR3aW5kb3coYXB0KSwgRE1fRVhFQ1VURVJQQywgMCwgKExQQVJBTSlwYXJhbXMpKQogICAgICAgIHsKICAgICAgICAgICAgRVJSKCJQb3N0TWVzc2FnZSBmYWlsZWQgd2l0aCBlcnJvciAlZFxuIiwgR2V0TGFzdEVycm9yKCkpOwogICAgICAgICAgICBociA9IEhSRVNVTFRfRlJPTV9XSU4zMihHZXRMYXN0RXJyb3IoKSk7CiAgICAgICAgfQogICAgfQogICAgZWxzZQogICAgewogICAgICAgIGlmIChociA9PSBTX09LKQogICAgICAgIHsKICAgICAgICAgICAgLyogb3RoZXJ3aXNlLCB3ZSBnbyB2aWEgUlBDIHJ1bnRpbWUgc28gdGhlIHN0dWIgYW5kIGNoYW5uZWwgYXJlbid0CiAgICAgICAgICAgICAqIG5lZWRlZCBoZXJlICovCiAgICAgICAgICAgIElScGNTdHViQnVmZmVyX1JlbGVhc2UocGFyYW1zLT5zdHViKTsKICAgICAgICAgICAgcGFyYW1zLT5zdHViID0gTlVMTDsKICAgICAgICAgICAgSVJwY0NoYW5uZWxCdWZmZXJfUmVsZWFzZShwYXJhbXMtPmNoYW4pOwogICAgICAgICAgICBwYXJhbXMtPmNoYW4gPSBOVUxMOwogICAgICAgIH0KCiAgICAgICAgLyogd2UgdXNlIGEgc2VwYXJhdGUgdGhyZWFkIGhlcmUgYmVjYXVzZSB3ZSBuZWVkIHRvIGJlIGFibGUgdG8KICAgICAgICAgKiBwdW1wIHRoZSBtZXNzYWdlIGxvb3AgaW4gdGhlIGFwcGxpY2F0aW9uIHRocmVhZDogaWYgd2UgZG8gbm90LAogICAgICAgICAqIGFueSB3aW5kb3dzIGNyZWF0ZWQgYnkgdGhpcyB0aHJlYWQgd2lsbCBoYW5nIGFuZCBSUENzIHRoYXQgdHJ5CiAgICAgICAgICogYW5kIHJlLWVudGVyIHRoaXMgU1RBIGZyb20gYW4gaW5jb21pbmcgc2VydmVyIHRocmVhZCB3aWxsCiAgICAgICAgICogZGVhZGxvY2suIEluc3RhbGxTaGllbGQgaXMgYW4gZXhhbXBsZSBvZiB0aGF0LgogICAgICAgICAqLwogICAgICAgIGlmICghUXVldWVVc2VyV29ya0l0ZW0ocnBjX3NlbmRyZWNlaXZlX3RocmVhZCwgcGFyYW1zLCBXVF9FWEVDVVRFREVGQVVMVCkpCiAgICAgICAgewogICAgICAgICAgICBFUlIoIlF1ZXVlVXNlcldvcmtJdGVtIGZhaWxlZCB3aXRoIGVycm9yICV4XG4iLCBHZXRMYXN0RXJyb3IoKSk7CiAgICAgICAgICAgIGhyID0gRV9VTkVYUEVDVEVEOwogICAgICAgIH0KICAgICAgICBlbHNlCiAgICAgICAgICAgIGhyID0gU19PSzsKICAgIH0KICAgIGlmIChhcHQpIGFwYXJ0bWVudF9yZWxlYXNlKGFwdCk7CgogICAgaWYgKGhyID09IFNfT0spCiAgICB7CiAgICAgICAgaWYgKFdhaXRGb3JTaW5nbGVPYmplY3QocGFyYW1zLT5oYW5kbGUsIDApKQogICAgICAgICAgICBociA9IENvV2FpdEZvck11bHRpcGxlSGFuZGxlcygwLCBJTkZJTklURSwgMSwgJnBhcmFtcy0+aGFuZGxlLCAmaW5kZXgpOwogICAgfQogICAgQ2xpZW50UnBjQ2hhbm5lbEJ1ZmZlcl9SZWxlYXNlRXZlbnRIYW5kbGUoVGhpcywgcGFyYW1zLT5oYW5kbGUpOwoKICAgIGlmIChociA9PSBTX09LKSBociA9IHBhcmFtcy0+aHI7CgogICAgc3RhdHVzID0gcGFyYW1zLT5zdGF0dXM7CiAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBwYXJhbXMpOwogICAgcGFyYW1zID0gTlVMTDsKCiAgICBpZiAoaHIpIHJldHVybiBocjsKICAgIAogICAgaWYgKHBzdGF0dXMpICpwc3RhdHVzID0gc3RhdHVzOwoKICAgIFRSQUNFKCJSUEMgY2FsbCBzdGF0dXM6IDB4JWx4XG4iLCBzdGF0dXMpOwogICAgaWYgKHN0YXR1cyA9PSBSUENfU19PSykKICAgICAgICBociA9IFNfT0s7CiAgICBlbHNlIGlmIChzdGF0dXMgPT0gUlBDX1NfQ0FMTF9GQUlMRUQpCiAgICAgICAgaHIgPSAqKEhSRVNVTFQgKilvbGVtc2ctPkJ1ZmZlcjsKICAgIGVsc2UKICAgICAgICBociA9IEhSRVNVTFRfRlJPTV9XSU4zMihzdGF0dXMpOwoKICAgIFRSQUNFKCItLSAweCUwOHhcbiIsIGhyKTsKCiAgICByZXR1cm4gaHI7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBTZXJ2ZXJScGNDaGFubmVsQnVmZmVyX0ZyZWVCdWZmZXIoTFBSUENDSEFOTkVMQlVGRkVSIGlmYWNlLCBSUENPTEVNRVNTQUdFKiBvbGVtc2cpCnsKICAgIFJQQ19NRVNTQUdFICptc2cgPSAoUlBDX01FU1NBR0UgKilvbGVtc2c7CiAgICBSUENfU1RBVFVTIHN0YXR1czsKCiAgICBUUkFDRSgiKCVwKVxuIiwgbXNnKTsKCiAgICBzdGF0dXMgPSBJX1JwY0ZyZWVCdWZmZXIobXNnKTsKCiAgICBUUkFDRSgiLS0gJWxkXG4iLCBzdGF0dXMpOwoKICAgIHJldHVybiBIUkVTVUxUX0ZST01fV0lOMzIoc3RhdHVzKTsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIENsaWVudFJwY0NoYW5uZWxCdWZmZXJfRnJlZUJ1ZmZlcihMUFJQQ0NIQU5ORUxCVUZGRVIgaWZhY2UsIFJQQ09MRU1FU1NBR0UqIG9sZW1zZykKewogICAgUlBDX01FU1NBR0UgKm1zZyA9IChSUENfTUVTU0FHRSAqKW9sZW1zZzsKICAgIFJQQ19TVEFUVVMgc3RhdHVzOwoKICAgIFRSQUNFKCIoJXApXG4iLCBtc2cpOwoKICAgIHN0YXR1cyA9IElfUnBjRnJlZUJ1ZmZlcihtc2cpOwoKICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIG1zZy0+UnBjSW50ZXJmYWNlSW5mb3JtYXRpb24pOwogICAgbXNnLT5ScGNJbnRlcmZhY2VJbmZvcm1hdGlvbiA9IE5VTEw7CgogICAgVFJBQ0UoIi0tICVsZFxuIiwgc3RhdHVzKTsKCiAgICByZXR1cm4gSFJFU1VMVF9GUk9NX1dJTjMyKHN0YXR1cyk7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBDbGllbnRScGNDaGFubmVsQnVmZmVyX0dldERlc3RDdHgoTFBSUENDSEFOTkVMQlVGRkVSIGlmYWNlLCBEV09SRCogcGR3RGVzdENvbnRleHQsIHZvaWQqKiBwcHZEZXN0Q29udGV4dCkKewogICAgQ2xpZW50UnBjQ2hhbm5lbEJ1ZmZlciAqVGhpcyA9IChDbGllbnRScGNDaGFubmVsQnVmZmVyICopaWZhY2U7CgogICAgVFJBQ0UoIiglcCwlcClcbiIsIHBkd0Rlc3RDb250ZXh0LCBwcHZEZXN0Q29udGV4dCk7CgogICAgKnBkd0Rlc3RDb250ZXh0ID0gVGhpcy0+ZGVzdF9jb250ZXh0OwogICAgKnBwdkRlc3RDb250ZXh0ID0gVGhpcy0+ZGVzdF9jb250ZXh0X2RhdGE7CgogICAgcmV0dXJuIFNfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBTZXJ2ZXJScGNDaGFubmVsQnVmZmVyX0dldERlc3RDdHgoTFBSUENDSEFOTkVMQlVGRkVSIGlmYWNlLCBEV09SRCogcGR3RGVzdENvbnRleHQsIHZvaWQqKiBwcHZEZXN0Q29udGV4dCkKewogICAgRklYTUUoIiglcCwlcCksIHN0dWIhXG4iLCBwZHdEZXN0Q29udGV4dCwgcHB2RGVzdENvbnRleHQpOwogICAgcmV0dXJuIEVfRkFJTDsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIFJwY0NoYW5uZWxCdWZmZXJfSXNDb25uZWN0ZWQoTFBSUENDSEFOTkVMQlVGRkVSIGlmYWNlKQp7CiAgICBUUkFDRSgiKClcbiIpOwogICAgLyogbmF0aXZlIGRvZXMgbm90aGluZyB0b28gKi8KICAgIHJldHVybiBTX09LOwp9CgpzdGF0aWMgY29uc3QgSVJwY0NoYW5uZWxCdWZmZXJWdGJsIENsaWVudFJwY0NoYW5uZWxCdWZmZXJWdGJsID0KewogICAgUnBjQ2hhbm5lbEJ1ZmZlcl9RdWVyeUludGVyZmFjZSwKICAgIFJwY0NoYW5uZWxCdWZmZXJfQWRkUmVmLAogICAgQ2xpZW50UnBjQ2hhbm5lbEJ1ZmZlcl9SZWxlYXNlLAogICAgQ2xpZW50UnBjQ2hhbm5lbEJ1ZmZlcl9HZXRCdWZmZXIsCiAgICBDbGllbnRScGNDaGFubmVsQnVmZmVyX1NlbmRSZWNlaXZlLAogICAgQ2xpZW50UnBjQ2hhbm5lbEJ1ZmZlcl9GcmVlQnVmZmVyLAogICAgQ2xpZW50UnBjQ2hhbm5lbEJ1ZmZlcl9HZXREZXN0Q3R4LAogICAgUnBjQ2hhbm5lbEJ1ZmZlcl9Jc0Nvbm5lY3RlZAp9OwoKc3RhdGljIGNvbnN0IElScGNDaGFubmVsQnVmZmVyVnRibCBTZXJ2ZXJScGNDaGFubmVsQnVmZmVyVnRibCA9CnsKICAgIFJwY0NoYW5uZWxCdWZmZXJfUXVlcnlJbnRlcmZhY2UsCiAgICBScGNDaGFubmVsQnVmZmVyX0FkZFJlZiwKICAgIFNlcnZlclJwY0NoYW5uZWxCdWZmZXJfUmVsZWFzZSwKICAgIFNlcnZlclJwY0NoYW5uZWxCdWZmZXJfR2V0QnVmZmVyLAogICAgU2VydmVyUnBjQ2hhbm5lbEJ1ZmZlcl9TZW5kUmVjZWl2ZSwKICAgIFNlcnZlclJwY0NoYW5uZWxCdWZmZXJfRnJlZUJ1ZmZlciwKICAgIFNlcnZlclJwY0NoYW5uZWxCdWZmZXJfR2V0RGVzdEN0eCwKICAgIFJwY0NoYW5uZWxCdWZmZXJfSXNDb25uZWN0ZWQKfTsKCi8qIHJldHVybnMgYSBjaGFubmVsIGJ1ZmZlciBmb3IgcHJveGllcyAqLwpIUkVTVUxUIFJQQ19DcmVhdGVDbGllbnRDaGFubmVsKGNvbnN0IE9YSUQgKm94aWQsIGNvbnN0IElQSUQgKmlwaWQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgZGVzdF9jb250ZXh0LCB2b2lkICpkZXN0X2NvbnRleHRfZGF0YSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJUnBjQ2hhbm5lbEJ1ZmZlciAqKmNoYW4pCnsKICAgIENsaWVudFJwY0NoYW5uZWxCdWZmZXIgKlRoaXM7CiAgICBXQ0hBUiAgICAgICAgICAgICAgICAgICBlbmRwb2ludFsyMDBdOwogICAgUlBDX0JJTkRJTkdfSEFORExFICAgICAgYmluZDsKICAgIFJQQ19TVEFUVVMgICAgICAgICAgICAgIHN0YXR1czsKICAgIExQV1NUUiAgICAgICAgICAgICAgICAgIHN0cmluZ19iaW5kaW5nOwoKICAgIC8qIGNvbm5lY3QgdG8gdGhlIGFwYXJ0bWVudCBsaXN0ZW5lciB0aHJlYWQgKi8KICAgIGdldF9ycGNfZW5kcG9pbnQoZW5kcG9pbnQsIG94aWQpOwoKICAgIFRSQUNFKCJwcm94eSBwaXBlOiBjb25uZWN0aW5nIHRvIGVuZHBvaW50OiAlc1xuIiwgZGVidWdzdHJfdyhlbmRwb2ludCkpOwoKICAgIHN0YXR1cyA9IFJwY1N0cmluZ0JpbmRpbmdDb21wb3NlVygKICAgICAgICBOVUxMLAogICAgICAgIHdzelJwY1RyYW5zcG9ydCwKICAgICAgICBOVUxMLAogICAgICAgIGVuZHBvaW50LAogICAgICAgIE5VTEwsCiAgICAgICAgJnN0cmluZ19iaW5kaW5nKTsKICAgICAgICAKICAgIGlmIChzdGF0dXMgPT0gUlBDX1NfT0spCiAgICB7CiAgICAgICAgc3RhdHVzID0gUnBjQmluZGluZ0Zyb21TdHJpbmdCaW5kaW5nVyhzdHJpbmdfYmluZGluZywgJmJpbmQpOwoKICAgICAgICBpZiAoc3RhdHVzID09IFJQQ19TX09LKQogICAgICAgIHsKICAgICAgICAgICAgSVBJRCBpcGlkMiA9ICppcGlkOyAvKiB3aHkgY2FuJ3QgUnBjQmluZGluZ1NldE9iamVjdCB0YWtlIGEgY29uc3Q/ICovCiAgICAgICAgICAgIHN0YXR1cyA9IFJwY0JpbmRpbmdTZXRPYmplY3QoYmluZCwgJmlwaWQyKTsKICAgICAgICAgICAgaWYgKHN0YXR1cyAhPSBSUENfU19PSykKICAgICAgICAgICAgICAgIFJwY0JpbmRpbmdGcmVlKCZiaW5kKTsKICAgICAgICB9CgogICAgICAgIFJwY1N0cmluZ0ZyZWVXKCZzdHJpbmdfYmluZGluZyk7CiAgICB9CgogICAgaWYgKHN0YXR1cyAhPSBSUENfU19PSykKICAgIHsKICAgICAgICBFUlIoIkNvdWxkbid0IGdldCBiaW5kaW5nIGZvciBlbmRwb2ludCAlcywgc3RhdHVzID0gJWxkXG4iLCBkZWJ1Z3N0cl93KGVuZHBvaW50KSwgc3RhdHVzKTsKICAgICAgICByZXR1cm4gSFJFU1VMVF9GUk9NX1dJTjMyKHN0YXR1cyk7CiAgICB9CgogICAgVGhpcyA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCAwLCBzaXplb2YoKlRoaXMpKTsKICAgIGlmICghVGhpcykKICAgIHsKICAgICAgICBScGNCaW5kaW5nRnJlZSgmYmluZCk7CiAgICAgICAgcmV0dXJuIEVfT1VUT0ZNRU1PUlk7CiAgICB9CgogICAgVGhpcy0+c3VwZXIubHBWdGJsID0gJkNsaWVudFJwY0NoYW5uZWxCdWZmZXJWdGJsOwogICAgVGhpcy0+c3VwZXIucmVmcyA9IDE7CiAgICBUaGlzLT5iaW5kID0gYmluZDsKICAgIGFwYXJ0bWVudF9nZXRveGlkKENPTV9DdXJyZW50QXB0KCksICZUaGlzLT5veGlkKTsKICAgIFRoaXMtPmRlc3RfY29udGV4dCA9IGRlc3RfY29udGV4dDsKICAgIFRoaXMtPmRlc3RfY29udGV4dF9kYXRhID0gZGVzdF9jb250ZXh0X2RhdGE7CiAgICBUaGlzLT5ldmVudCA9IE5VTEw7CgogICAgKmNoYW4gPSAoSVJwY0NoYW5uZWxCdWZmZXIqKVRoaXM7CgogICAgcmV0dXJuIFNfT0s7Cn0KCkhSRVNVTFQgUlBDX0NyZWF0ZVNlcnZlckNoYW5uZWwoSVJwY0NoYW5uZWxCdWZmZXIgKipjaGFuKQp7CiAgICBScGNDaGFubmVsQnVmZmVyICpUaGlzID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIDAsIHNpemVvZigqVGhpcykpOwogICAgaWYgKCFUaGlzKQogICAgICAgIHJldHVybiBFX09VVE9GTUVNT1JZOwoKICAgIFRoaXMtPmxwVnRibCA9ICZTZXJ2ZXJScGNDaGFubmVsQnVmZmVyVnRibDsKICAgIFRoaXMtPnJlZnMgPSAxOwogICAgCiAgICAqY2hhbiA9IChJUnBjQ2hhbm5lbEJ1ZmZlciopVGhpczsKCiAgICByZXR1cm4gU19PSzsKfQoKCnZvaWQgUlBDX0V4ZWN1dGVDYWxsKHN0cnVjdCBkaXNwYXRjaF9wYXJhbXMgKnBhcmFtcykKewogICAgcGFyYW1zLT5ociA9IElScGNTdHViQnVmZmVyX0ludm9rZShwYXJhbXMtPnN0dWIsIHBhcmFtcy0+bXNnLCBwYXJhbXMtPmNoYW4pOwoKICAgIElScGNTdHViQnVmZmVyX1JlbGVhc2UocGFyYW1zLT5zdHViKTsKICAgIElScGNDaGFubmVsQnVmZmVyX1JlbGVhc2UocGFyYW1zLT5jaGFuKTsKICAgIGlmIChwYXJhbXMtPmhhbmRsZSkgU2V0RXZlbnQocGFyYW1zLT5oYW5kbGUpOwp9CgpzdGF0aWMgdm9pZCBfX1JQQ19TVFVCIGRpc3BhdGNoX3JwYyhSUENfTUVTU0FHRSAqbXNnKQp7CiAgICBzdHJ1Y3QgZGlzcGF0Y2hfcGFyYW1zICpwYXJhbXM7CiAgICBBUEFSVE1FTlQgKmFwdDsKICAgIElQSUQgaXBpZDsKICAgIEhSRVNVTFQgaHI7CgogICAgUnBjQmluZGluZ0lucU9iamVjdChtc2ctPkhhbmRsZSwgJmlwaWQpOwoKICAgIFRSQUNFKCJpcGlkID0gJXMsIGlNZXRob2QgPSAlZFxuIiwgZGVidWdzdHJfZ3VpZCgmaXBpZCksIG1zZy0+UHJvY051bSk7CgogICAgcGFyYW1zID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIDAsIHNpemVvZigqcGFyYW1zKSk7CiAgICBpZiAoIXBhcmFtcykgcmV0dXJuIFJwY1JhaXNlRXhjZXB0aW9uKEVfT1VUT0ZNRU1PUlkpOwoKICAgIGhyID0gaXBpZF9nZXRfZGlzcGF0Y2hfcGFyYW1zKCZpcGlkLCAmYXB0LCAmcGFyYW1zLT5zdHViLCAmcGFyYW1zLT5jaGFuKTsKICAgIGlmIChociAhPSBTX09LKQogICAgewogICAgICAgIEVSUigibm8gYXBhcnRtZW50IGZvdW5kIGZvciBpcGlkICVzXG4iLCBkZWJ1Z3N0cl9ndWlkKCZpcGlkKSk7CiAgICAgICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgcGFyYW1zKTsKICAgICAgICByZXR1cm4gUnBjUmFpc2VFeGNlcHRpb24oaHIpOwogICAgfQoKICAgIHBhcmFtcy0+bXNnID0gKFJQQ09MRU1FU1NBR0UgKiltc2c7CiAgICBwYXJhbXMtPnN0YXR1cyA9IFJQQ19TX09LOwogICAgcGFyYW1zLT5ociA9IFNfT0s7CiAgICBwYXJhbXMtPmhhbmRsZSA9IE5VTEw7CgogICAgLyogTm90ZTogdGhpcyBpcyB0aGUgaW1wb3J0YW50IGRpZmZlcmVuY2UgYmV0d2VlbiBTVEFzIGFuZCBNVEFzIC0gd2UKICAgICAqIGFsd2F5cyBleGVjdXRlIFJQQ3MgdG8gU1RBcyBpbiB0aGUgdGhyZWFkIHRoYXQgb3JpZ2luYWxseSBjcmVhdGVkIHRoZQogICAgICogYXBhcnRtZW50IChpLmUuIHRoZSBvbmUgdGhhdCBwdW1wcyBtZXNzYWdlcyB0byB0aGUgd2luZG93KSAqLwogICAgaWYgKCFhcHQtPm11bHRpX3RocmVhZGVkKQogICAgewogICAgICAgIHBhcmFtcy0+aGFuZGxlID0gQ3JlYXRlRXZlbnRXKE5VTEwsIEZBTFNFLCBGQUxTRSwgTlVMTCk7CgogICAgICAgIFRSQUNFKCJDYWxsaW5nIGFwYXJ0bWVudCB0aHJlYWQgMHglMDh4Li4uXG4iLCBhcHQtPnRpZCk7CgogICAgICAgIGlmIChQb3N0TWVzc2FnZVcoYXBhcnRtZW50X2dldHdpbmRvdyhhcHQpLCBETV9FWEVDVVRFUlBDLCAwLCAoTFBBUkFNKXBhcmFtcykpCiAgICAgICAgICAgIFdhaXRGb3JTaW5nbGVPYmplY3QocGFyYW1zLT5oYW5kbGUsIElORklOSVRFKTsKICAgICAgICBlbHNlCiAgICAgICAgewogICAgICAgICAgICBFUlIoIlBvc3RNZXNzYWdlIGZhaWxlZCB3aXRoIGVycm9yICVkXG4iLCBHZXRMYXN0RXJyb3IoKSk7CiAgICAgICAgICAgIElScGNDaGFubmVsQnVmZmVyX1JlbGVhc2UocGFyYW1zLT5jaGFuKTsKICAgICAgICAgICAgSVJwY1N0dWJCdWZmZXJfUmVsZWFzZShwYXJhbXMtPnN0dWIpOwogICAgICAgIH0KICAgICAgICBDbG9zZUhhbmRsZShwYXJhbXMtPmhhbmRsZSk7CiAgICB9CiAgICBlbHNlCiAgICB7CiAgICAgICAgQk9PTCBqb2luZWQgPSBGQUxTRTsKICAgICAgICBpZiAoIUNPTV9DdXJyZW50SW5mbygpLT5hcHQpCiAgICAgICAgewogICAgICAgICAgICBhcGFydG1lbnRfam9pbm10YSgpOwogICAgICAgICAgICBqb2luZWQgPSBUUlVFOwogICAgICAgIH0KICAgICAgICBSUENfRXhlY3V0ZUNhbGwocGFyYW1zKTsKICAgICAgICBpZiAoam9pbmVkKQogICAgICAgIHsKICAgICAgICAgICAgYXBhcnRtZW50X3JlbGVhc2UoQ09NX0N1cnJlbnRJbmZvKCktPmFwdCk7CiAgICAgICAgICAgIENPTV9DdXJyZW50SW5mbygpLT5hcHQgPSBOVUxMOwogICAgICAgIH0KICAgIH0KCiAgICBociA9IHBhcmFtcy0+aHI7CiAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBwYXJhbXMpOwoKICAgIGFwYXJ0bWVudF9yZWxlYXNlKGFwdCk7CgogICAgLyogaWYgSVJwY1N0dWJCdWZmZXJfSW52b2tlIGZhaWxzLCB3ZSBzaG91bGQgcmFpc2UgYW4gZXhjZXB0aW9uIHRvIHRlbGwKICAgICAqIHRoZSBSUEMgcnVudGltZSB0aGF0IHRoZSBjYWxsIGZhaWxlZCAqLwogICAgaWYgKGhyKSBScGNSYWlzZUV4Y2VwdGlvbihocik7Cn0KCi8qIHN0dWIgcmVnaXN0cmF0aW9uICovCkhSRVNVTFQgUlBDX1JlZ2lzdGVySW50ZXJmYWNlKFJFRklJRCByaWlkKQp7CiAgICBzdHJ1Y3QgcmVnaXN0ZXJlZF9pZiAqcmlmOwogICAgQk9PTCBmb3VuZCA9IEZBTFNFOwogICAgSFJFU1VMVCBociA9IFNfT0s7CiAgICAKICAgIFRSQUNFKCIoJXMpXG4iLCBkZWJ1Z3N0cl9ndWlkKHJpaWQpKTsKCiAgICBFbnRlckNyaXRpY2FsU2VjdGlvbigmY3NSZWdJZik7CiAgICBMSVNUX0ZPUl9FQUNIX0VOVFJZKHJpZiwgJnJlZ2lzdGVyZWRfaW50ZXJmYWNlcywgc3RydWN0IHJlZ2lzdGVyZWRfaWYsIGVudHJ5KQogICAgewogICAgICAgIGlmIChJc0VxdWFsR1VJRCgmcmlmLT5JZi5JbnRlcmZhY2VJZC5TeW50YXhHVUlELCByaWlkKSkKICAgICAgICB7CiAgICAgICAgICAgIHJpZi0+cmVmcysrOwogICAgICAgICAgICBmb3VuZCA9IFRSVUU7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIH0KICAgIH0KICAgIGlmICghZm91bmQpCiAgICB7CiAgICAgICAgVFJBQ0UoIkNyZWF0aW5nIG5ldyBpbnRlcmZhY2VcbiIpOwoKICAgICAgICByaWYgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgSEVBUF9aRVJPX01FTU9SWSwgc2l6ZW9mKCpyaWYpKTsKICAgICAgICBpZiAocmlmKQogICAgICAgIHsKICAgICAgICAgICAgUlBDX1NUQVRVUyBzdGF0dXM7CgogICAgICAgICAgICByaWYtPnJlZnMgPSAxOwogICAgICAgICAgICByaWYtPklmLkxlbmd0aCA9IHNpemVvZihSUENfU0VSVkVSX0lOVEVSRkFDRSk7CiAgICAgICAgICAgIC8qIFJQQyBpbnRlcmZhY2UgSUQgPSBDT00gaW50ZXJmYWNlIElEICovCiAgICAgICAgICAgIHJpZi0+SWYuSW50ZXJmYWNlSWQuU3ludGF4R1VJRCA9ICpyaWlkOwogICAgICAgICAgICByaWYtPklmLkRpc3BhdGNoVGFibGUgPSAmcnBjX2Rpc3BhdGNoOwogICAgICAgICAgICAvKiBhbGwgb3RoZXIgZmllbGRzIGFyZSAwLCBpbmNsdWRpbmcgdGhlIHZlcnNpb24gYXNDT00gb2JqZWN0cwogICAgICAgICAgICAgKiBhbHdheXMgaGF2ZSBhIHZlcnNpb24gb2YgMC4wICovCiAgICAgICAgICAgIHN0YXR1cyA9IFJwY1NlcnZlclJlZ2lzdGVySWZFeCgKICAgICAgICAgICAgICAgIChSUENfSUZfSEFORExFKSZyaWYtPklmLAogICAgICAgICAgICAgICAgTlVMTCwgTlVMTCwKICAgICAgICAgICAgICAgIFJQQ19JRl9PTEUgfCBSUENfSUZfQVVUT0xJU1RFTiwKICAgICAgICAgICAgICAgIFJQQ19DX0xJU1RFTl9NQVhfQ0FMTFNfREVGQVVMVCwKICAgICAgICAgICAgICAgIE5VTEwpOwogICAgICAgICAgICBpZiAoc3RhdHVzID09IFJQQ19TX09LKQogICAgICAgICAgICAgICAgbGlzdF9hZGRfdGFpbCgmcmVnaXN0ZXJlZF9pbnRlcmZhY2VzLCAmcmlmLT5lbnRyeSk7CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgRVJSKCJScGNTZXJ2ZXJSZWdpc3RlcklmRXggZmFpbGVkIHdpdGggZXJyb3IgJWxkXG4iLCBzdGF0dXMpOwogICAgICAgICAgICAgICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgcmlmKTsKICAgICAgICAgICAgICAgIGhyID0gSFJFU1VMVF9GUk9NX1dJTjMyKHN0YXR1cyk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgZWxzZQogICAgICAgICAgICBociA9IEVfT1VUT0ZNRU1PUlk7CiAgICB9CiAgICBMZWF2ZUNyaXRpY2FsU2VjdGlvbigmY3NSZWdJZik7CiAgICByZXR1cm4gaHI7Cn0KCi8qIHN0dWIgdW5yZWdpc3RyYXRpb24gKi8Kdm9pZCBSUENfVW5yZWdpc3RlckludGVyZmFjZShSRUZJSUQgcmlpZCkKewogICAgc3RydWN0IHJlZ2lzdGVyZWRfaWYgKnJpZjsKICAgIEVudGVyQ3JpdGljYWxTZWN0aW9uKCZjc1JlZ0lmKTsKICAgIExJU1RfRk9SX0VBQ0hfRU5UUlkocmlmLCAmcmVnaXN0ZXJlZF9pbnRlcmZhY2VzLCBzdHJ1Y3QgcmVnaXN0ZXJlZF9pZiwgZW50cnkpCiAgICB7CiAgICAgICAgaWYgKElzRXF1YWxHVUlEKCZyaWYtPklmLkludGVyZmFjZUlkLlN5bnRheEdVSUQsIHJpaWQpKQogICAgICAgIHsKICAgICAgICAgICAgaWYgKCEtLXJpZi0+cmVmcykKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgUnBjU2VydmVyVW5yZWdpc3RlcklmKChSUENfSUZfSEFORExFKSZyaWYtPklmLCBOVUxMLCBUUlVFKTsKICAgICAgICAgICAgICAgIGxpc3RfcmVtb3ZlKCZyaWYtPmVudHJ5KTsKICAgICAgICAgICAgICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIHJpZik7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgfQogICAgfQogICAgTGVhdmVDcml0aWNhbFNlY3Rpb24oJmNzUmVnSWYpOwp9CgovKiBtYWtlIHRoZSBhcGFydG1lbnQgcmVhY2hhYmxlIGJ5IG90aGVyIHRocmVhZHMgYW5kIHByb2Nlc3NlcyBhbmQgY3JlYXRlIHRoZQogKiBJUmVtVW5rbm93biBvYmplY3QgKi8Kdm9pZCBSUENfU3RhcnRSZW1vdGluZyhzdHJ1Y3QgYXBhcnRtZW50ICphcHQpCnsKICAgIGlmICghSW50ZXJsb2NrZWRFeGNoYW5nZSgmYXB0LT5yZW1vdGluZ19zdGFydGVkLCBUUlVFKSkKICAgIHsKICAgICAgICBXQ0hBUiBlbmRwb2ludFsyMDBdOwogICAgICAgIFJQQ19TVEFUVVMgc3RhdHVzOwoKICAgICAgICBnZXRfcnBjX2VuZHBvaW50KGVuZHBvaW50LCAmYXB0LT5veGlkKTsKICAgIAogICAgICAgIHN0YXR1cyA9IFJwY1NlcnZlclVzZVByb3RzZXFFcFcoCiAgICAgICAgICAgIHdzelJwY1RyYW5zcG9ydCwKICAgICAgICAgICAgUlBDX0NfUFJPVFNFUV9NQVhfUkVRU19ERUZBVUxULAogICAgICAgICAgICBlbmRwb2ludCwKICAgICAgICAgICAgTlVMTCk7CiAgICAgICAgaWYgKHN0YXR1cyAhPSBSUENfU19PSykKICAgICAgICAgICAgRVJSKCJDb3VsZG4ndCByZWdpc3RlciBlbmRwb2ludCAlc1xuIiwgZGVidWdzdHJfdyhlbmRwb2ludCkpOwoKICAgICAgICAvKiBGSVhNRTogbW92ZSByZW1vdGUgdW5rbm93biBleHBvcnRpbmcgaW50byB0aGlzIGZ1bmN0aW9uICovCiAgICB9CiAgICBzdGFydF9hcGFydG1lbnRfcmVtb3RlX3Vua25vd24oKTsKfQoKCnN0YXRpYyBIUkVTVUxUIGNyZWF0ZV9zZXJ2ZXIoUkVGQ0xTSUQgcmNsc2lkKQp7CiAgICBzdGF0aWMgY29uc3QgV0NIQVIgIHdzekxvY2FsU2VydmVyMzJbXSA9IHsgJ0wnLCdvJywnYycsJ2EnLCdsJywnUycsJ2UnLCdyJywndicsJ2UnLCdyJywnMycsJzInLDAgfTsKICAgIHN0YXRpYyBjb25zdCBXQ0hBUiAgZW1iZWRkaW5nW10gPSB7ICcgJywgJy0nLCdFJywnbScsJ2InLCdlJywnZCcsJ2QnLCdpJywnbicsJ2cnLDAgfTsKICAgIEhLRVkgICAgICAgICAgICAgICAga2V5OwogICAgSFJFU1VMVCAgICAgICAgICAgICBocmVzOwogICAgV0NIQVIgICAgICAgICAgICAgICBjb21tYW5kW01BWF9QQVRIK3NpemVvZihlbWJlZGRpbmcpL3NpemVvZihXQ0hBUildOwogICAgRFdPUkQgICAgICAgICAgICAgICBzaXplID0gKE1BWF9QQVRIKzEpICogc2l6ZW9mKFdDSEFSKTsKICAgIFNUQVJUVVBJTkZPVyAgICAgICAgc2luZm87CiAgICBQUk9DRVNTX0lORk9STUFUSU9OIHBpbmZvOwoKICAgIGhyZXMgPSBDT01fT3BlbktleUZvckNMU0lEKHJjbHNpZCwgd3N6TG9jYWxTZXJ2ZXIzMiwgS0VZX1JFQUQsICZrZXkpOwogICAgaWYgKEZBSUxFRChocmVzKSkgewogICAgICAgIEVSUigiY2xhc3MgJXMgbm90IHJlZ2lzdGVyZWRcbiIsIGRlYnVnc3RyX2d1aWQocmNsc2lkKSk7CiAgICAgICAgcmV0dXJuIGhyZXM7CiAgICB9CgogICAgaHJlcyA9IFJlZ1F1ZXJ5VmFsdWVFeFcoa2V5LCBOVUxMLCBOVUxMLCBOVUxMLCAoTFBCWVRFKWNvbW1hbmQsICZzaXplKTsKICAgIFJlZ0Nsb3NlS2V5KGtleSk7CiAgICBpZiAoaHJlcykgewogICAgICAgIFdBUk4oIk5vIGRlZmF1bHQgdmFsdWUgZm9yIExvY2FsU2VydmVyMzIga2V5XG4iKTsKICAgICAgICByZXR1cm4gUkVHREJfRV9DTEFTU05PVFJFRzsgLyogRklYTUU6IGNoZWNrIHJldHZhbCAqLwogICAgfQoKICAgIG1lbXNldCgmc2luZm8sMCxzaXplb2Yoc2luZm8pKTsKICAgIHNpbmZvLmNiID0gc2l6ZW9mKHNpbmZvKTsKCiAgICAvKiBFWEUgc2VydmVycyBhcmUgc3RhcnRlZCB3aXRoIHRoZSAtRW1iZWRkaW5nIHN3aXRjaC4gKi8KCiAgICBzdHJjYXRXKGNvbW1hbmQsIGVtYmVkZGluZyk7CgogICAgVFJBQ0UoImFjdGl2YXRpbmcgbG9jYWwgc2VydmVyICVzIGZvciAlc1xuIiwgZGVidWdzdHJfdyhjb21tYW5kKSwgZGVidWdzdHJfZ3VpZChyY2xzaWQpKTsKCiAgICAvKiBGSVhNRTogV2luMjAwMyBzdXBwb3J0cyBhIFNlcnZlckV4ZWN1dGFibGUgdmFsdWUgdGhhdCBpcyBwYXNzZWQgaW50bwogICAgICogQ3JlYXRlUHJvY2VzcyAqLwogICAgaWYgKCFDcmVhdGVQcm9jZXNzVyhOVUxMLCBjb21tYW5kLCBOVUxMLCBOVUxMLCBGQUxTRSwgMCwgTlVMTCwgTlVMTCwgJnNpbmZvLCAmcGluZm8pKSB7CiAgICAgICAgV0FSTigiZmFpbGVkIHRvIHJ1biBsb2NhbCBzZXJ2ZXIgJXNcbiIsIGRlYnVnc3RyX3coY29tbWFuZCkpOwogICAgICAgIHJldHVybiBIUkVTVUxUX0ZST01fV0lOMzIoR2V0TGFzdEVycm9yKCkpOwogICAgfQogICAgQ2xvc2VIYW5kbGUocGluZm8uaFByb2Nlc3MpOwogICAgQ2xvc2VIYW5kbGUocGluZm8uaFRocmVhZCk7CgogICAgcmV0dXJuIFNfT0s7Cn0KCi8qCiAqIHN0YXJ0X2xvY2FsX3NlcnZpY2UoKSAgLSBzdGFydCBhIHNlcnZpY2UgZ2l2ZW4gaXRzIG5hbWUgYW5kIHBhcmFtZXRlcnMKICovCnN0YXRpYyBEV09SRCBzdGFydF9sb2NhbF9zZXJ2aWNlKExQQ1dTVFIgbmFtZSwgRFdPUkQgbnVtLCBMUENXU1RSICpwYXJhbXMpCnsKICAgIFNDX0hBTkRMRSBoYW5kbGUsIGhzdmM7CiAgICBEV09SRCAgICAgciA9IEVSUk9SX0ZVTkNUSU9OX0ZBSUxFRDsKCiAgICBUUkFDRSgiU3RhcnRpbmcgc2VydmljZSAlcyAlZCBwYXJhbXNcbiIsIGRlYnVnc3RyX3cobmFtZSksIG51bSk7CgogICAgaGFuZGxlID0gT3BlblNDTWFuYWdlclcoTlVMTCwgTlVMTCwgU0NfTUFOQUdFUl9DT05ORUNUKTsKICAgIGlmICghaGFuZGxlKQogICAgICAgIHJldHVybiByOwogICAgaHN2YyA9IE9wZW5TZXJ2aWNlVyhoYW5kbGUsIG5hbWUsIFNFUlZJQ0VfU1RBUlQpOwogICAgaWYgKGhzdmMpCiAgICB7CiAgICAgICAgaWYoU3RhcnRTZXJ2aWNlVyhoc3ZjLCBudW0sIHBhcmFtcykpCiAgICAgICAgICAgIHIgPSBFUlJPUl9TVUNDRVNTOwogICAgICAgIGVsc2UKICAgICAgICAgICAgciA9IEdldExhc3RFcnJvcigpOwogICAgICAgIGlmIChyID09IEVSUk9SX1NFUlZJQ0VfQUxSRUFEWV9SVU5OSU5HKQogICAgICAgICAgICByID0gRVJST1JfU1VDQ0VTUzsKICAgICAgICBDbG9zZVNlcnZpY2VIYW5kbGUoaHN2Yyk7CiAgICB9CiAgICBlbHNlCiAgICAgICAgciA9IEdldExhc3RFcnJvcigpOwogICAgQ2xvc2VTZXJ2aWNlSGFuZGxlKGhhbmRsZSk7CgogICAgVFJBQ0UoIlN0YXJ0U2VydmljZSByZXR1cm5lZCBlcnJvciAlZCAoJXMpXG4iLCByLCAociA9PSBFUlJPUl9TVUNDRVNTKSA/ICJvayI6ImZhaWxlZCIpOwoKICAgIHJldHVybiByOwp9CgovKgogKiBjcmVhdGVfbG9jYWxfc2VydmljZSgpICAtIHN0YXJ0IGEgQ09NIHNlcnZlciBpbiBhIHNlcnZpY2UKICoKICogICBUbyBzdGFydCBhIExvY2FsIFNlcnZpY2UsIHdlIHJlYWQgdGhlIEFwcElEIHZhbHVlIHVuZGVyCiAqIHRoZSBjbGFzcydzIENMU0lEIGtleSwgdGhlbiBvcGVuIHRoZSBIS0NSXFxBcHBJZCBrZXkgc3BlY2lmaWVkCiAqIHRoZXJlIGFuZCBjaGVjayBmb3IgYSBMb2NhbFNlcnZpY2UgdmFsdWUuCiAqCiAqIE5vdGU6ICBMb2NhbCBTZXJ2aWNlcyBhcmUgbm90IHN1cHBvcnRlZCB1bmRlciBXaW5kb3dzIDl4CiAqLwpzdGF0aWMgSFJFU1VMVCBjcmVhdGVfbG9jYWxfc2VydmljZShSRUZDTFNJRCByY2xzaWQpCnsKICAgIEhSRVNVTFQgaHJlczsKICAgIFdDSEFSIGJ1ZltDSEFSU19JTl9HVUlEXTsKICAgIHN0YXRpYyBjb25zdCBXQ0hBUiBzekxvY2FsU2VydmljZVtdID0geyAnTCcsJ28nLCdjJywnYScsJ2wnLCdTJywnZScsJ3InLCd2JywnaScsJ2MnLCdlJywwIH07CiAgICBzdGF0aWMgY29uc3QgV0NIQVIgc3pTZXJ2aWNlUGFyYW1zW10gPSB7J1MnLCdlJywncicsJ3YnLCdpJywnYycsJ2UnLCdQJywnYScsJ3InLCdhJywnbScsJ3MnLDB9OwogICAgSEtFWSBoa2V5OwogICAgTE9ORyByOwogICAgRFdPUkQgdHlwZSwgc3o7CgogICAgVFJBQ0UoIkF0dGVtcHRpbmcgdG8gc3RhcnQgTG9jYWwgc2VydmljZSBmb3IgJXNcbiIsIGRlYnVnc3RyX2d1aWQocmNsc2lkKSk7CgogICAgaHJlcyA9IENPTV9PcGVuS2V5Rm9yQXBwSWRGcm9tQ0xTSUQocmNsc2lkLCBLRVlfUkVBRCwgJmhrZXkpOwogICAgaWYgKEZBSUxFRChocmVzKSkKICAgICAgICByZXR1cm4gaHJlczsKCiAgICAvKiByZWFkIHRoZSBMb2NhbFNlcnZpY2UgYW5kIFNlcnZpY2VQYXJhbWV0ZXJzIHZhbHVlcyBmcm9tIHRoZSBBcHBJRCBrZXkgKi8KICAgIHN6ID0gc2l6ZW9mIGJ1ZjsKICAgIHIgPSBSZWdRdWVyeVZhbHVlRXhXKGhrZXksIHN6TG9jYWxTZXJ2aWNlLCBOVUxMLCAmdHlwZSwgKExQQllURSlidWYsICZzeik7CiAgICBpZiAocj09RVJST1JfU1VDQ0VTUyAmJiB0eXBlPT1SRUdfU1opCiAgICB7CiAgICAgICAgRFdPUkQgbnVtX2FyZ3MgPSAwOwogICAgICAgIExQV1NUUiBhcmdzWzFdID0geyBOVUxMIH07CgogICAgICAgIC8qCiAgICAgICAgICogRklYTUU6IEknbSBub3QgcmVhbGx5IHN1cmUgaG93IHRvIGRlYWwgd2l0aCB0aGUgc2VydmljZSBwYXJhbWV0ZXJzLgogICAgICAgICAqICAgICAgICBJIHN1c3BlY3QgdGhhdCB0aGUgc3RyaW5nIHJldHVybmVkIGZyb20gUmVnUXVlcnlWYWx1ZUV4VwogICAgICAgICAqICAgICAgICBzaG91bGQgYmUgc3BsaXQgaW50byBhIG51bWJlciBvZiBhcmd1bWVudHMgYnkgc3BhY2VzLgogICAgICAgICAqICAgICAgICBJdCB3b3VsZCBtYWtlIG1vcmUgc2Vuc2UgaWYgU2VydmljZVBhcmFtcyBjb250YWluZWQgYQogICAgICAgICAqICAgICAgICBSRUdfTVVMVElfU1ogaGVyZSwgYnV0IGl0J3MgYSBSRUdfU1ogZm9yIHRoZSBzZXJ2aWNlcwogICAgICAgICAqICAgICAgICB0aGF0IEknbSBpbnRlcmVzdGVkIGluIGZvciB0aGUgbW9tZW50LgogICAgICAgICAqLwogICAgICAgIHIgPSBSZWdRdWVyeVZhbHVlRXhXKGhrZXksIHN6U2VydmljZVBhcmFtcywgTlVMTCwgJnR5cGUsIE5VTEwsICZzeik7CiAgICAgICAgaWYgKHIgPT0gRVJST1JfU1VDQ0VTUyAmJiB0eXBlID09IFJFR19TWiAmJiBzeikKICAgICAgICB7CiAgICAgICAgICAgIGFyZ3NbMF0gPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSxIRUFQX1pFUk9fTUVNT1JZLHN6KTsKICAgICAgICAgICAgbnVtX2FyZ3MrKzsKICAgICAgICAgICAgUmVnUXVlcnlWYWx1ZUV4Vyhoa2V5LCBzelNlcnZpY2VQYXJhbXMsIE5VTEwsICZ0eXBlLCAoTFBCWVRFKWFyZ3NbMF0sICZzeik7CiAgICAgICAgfQogICAgICAgIHIgPSBzdGFydF9sb2NhbF9zZXJ2aWNlKGJ1ZiwgbnVtX2FyZ3MsIChMUENXU1RSICopYXJncyk7CiAgICAgICAgaWYgKHIgIT0gRVJST1JfU1VDQ0VTUykKICAgICAgICAgICAgaHJlcyA9IFJFR0RCX0VfQ0xBU1NOT1RSRUc7IC8qIEZJWE1FOiBjaGVjayByZXR2YWwgKi8KICAgICAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLDAsYXJnc1swXSk7CiAgICB9CiAgICBlbHNlCiAgICB7CiAgICAgICAgV0FSTigiTm8gTG9jYWxTZXJ2aWNlIHZhbHVlXG4iKTsKICAgICAgICBocmVzID0gUkVHREJfRV9DTEFTU05PVFJFRzsgLyogRklYTUU6IGNoZWNrIHJldHZhbCAqLwogICAgfQogICAgUmVnQ2xvc2VLZXkoaGtleSk7CgogICAgcmV0dXJuIGhyZXM7Cn0KCgpzdGF0aWMgdm9pZCBnZXRfbG9jYWxzZXJ2ZXJfcGlwZV9uYW1lKFdDSEFSICpwaXBlZm4sIFJFRkNMU0lEIHJjbHNpZCkKewogICAgc3RhdGljIGNvbnN0IFdDSEFSIHdzelBpcGVSZWZbXSA9IHsnXFwnLCdcXCcsJy4nLCdcXCcsJ3AnLCdpJywncCcsJ2UnLCdcXCcsMH07CiAgICBzdHJjcHlXKHBpcGVmbiwgd3N6UGlwZVJlZik7CiAgICBTdHJpbmdGcm9tR1VJRDIocmNsc2lkLCBwaXBlZm4gKyBzaXplb2Yod3N6UGlwZVJlZikvc2l6ZW9mKHdzelBpcGVSZWZbMF0pIC0gMSwgQ0hBUlNfSU5fR1VJRCk7Cn0KCi8qIEZJWE1FOiBzaG91bGQgY2FsbCB0byBycGNzcyBpbnN0ZWFkICovCkhSRVNVTFQgUlBDX0dldExvY2FsQ2xhc3NPYmplY3QoUkVGQ0xTSUQgcmNsc2lkLCBSRUZJSUQgaWlkLCBMUFZPSUQgKnBwdikKewogICAgSFJFU1VMVCAgICAgICAgaHJlczsKICAgIEhBTkRMRSAgICAgICAgIGhQaXBlOwogICAgV0NIQVIgICAgICAgICAgcGlwZWZuWzEwMF07CiAgICBEV09SRCAgICAgICAgICByZXMsIGJ1ZmZlcmxlbjsKICAgIGNoYXIgICAgICAgICAgIG1hcnNoYWxidWZmZXJbMjAwXTsKICAgIElTdHJlYW0gICAgICAgKnBTdG07CiAgICBMQVJHRV9JTlRFR0VSICBzZWVrdG87CiAgICBVTEFSR0VfSU5URUdFUiBuZXdwb3M7CiAgICBpbnQgICAgICAgICAgICB0cmllcyA9IDA7CgogICAgc3RhdGljIGNvbnN0IGludCBNQVhUUklFUyA9IDMwOyAvKiAzMCBzZWNvbmRzICovCgogICAgVFJBQ0UoInJjbHNpZD0lcywgaWlkPSVzXG4iLCBkZWJ1Z3N0cl9ndWlkKHJjbHNpZCksIGRlYnVnc3RyX2d1aWQoaWlkKSk7CgogICAgZ2V0X2xvY2Fsc2VydmVyX3BpcGVfbmFtZShwaXBlZm4sIHJjbHNpZCk7CgogICAgd2hpbGUgKHRyaWVzKysgPCBNQVhUUklFUykgewogICAgICAgIFRSQUNFKCJ3YWl0aW5nIGZvciAlc1xuIiwgZGVidWdzdHJfdyhwaXBlZm4pKTsKICAgICAgCiAgICAgICAgV2FpdE5hbWVkUGlwZVcoIHBpcGVmbiwgTk1QV0FJVF9XQUlUX0ZPUkVWRVIgKTsKICAgICAgICBoUGlwZSA9IENyZWF0ZUZpbGVXKHBpcGVmbiwgR0VORVJJQ19SRUFEIHwgR0VORVJJQ19XUklURSwgMCwgTlVMTCwgT1BFTl9FWElTVElORywgMCwgMCk7CiAgICAgICAgaWYgKGhQaXBlID09IElOVkFMSURfSEFORExFX1ZBTFVFKSB7CiAgICAgICAgICAgIGlmICh0cmllcyA9PSAxKSB7CiAgICAgICAgICAgICAgICBpZiAoIChocmVzID0gY3JlYXRlX2xvY2FsX3NlcnZpY2UocmNsc2lkKSkgJiYKICAgICAgICAgICAgICAgICAgICAgKGhyZXMgPSBjcmVhdGVfc2VydmVyKHJjbHNpZCkpICkKICAgICAgICAgICAgICAgICAgICByZXR1cm4gaHJlczsKICAgICAgICAgICAgICAgIFNsZWVwKDEwMDApOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgV0FSTigiQ29ubmVjdGluZyB0byAlcywgbm8gcmVzcG9uc2UgeWV0LCByZXRyeWluZzogbGUgaXMgJXhcbiIsIGRlYnVnc3RyX3cocGlwZWZuKSwgR2V0TGFzdEVycm9yKCkpOwogICAgICAgICAgICAgICAgU2xlZXAoMTAwMCk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgfQogICAgICAgIGJ1ZmZlcmxlbiA9IDA7CiAgICAgICAgaWYgKCFSZWFkRmlsZShoUGlwZSxtYXJzaGFsYnVmZmVyLHNpemVvZihtYXJzaGFsYnVmZmVyKSwmYnVmZmVybGVuLE5VTEwpKSB7CiAgICAgICAgICAgIEZJWE1FKCJGYWlsZWQgdG8gcmVhZCBtYXJzaGFsIGlkIGZyb20gY2xhc3NmYWN0b3J5IG9mICVzLlxuIixkZWJ1Z3N0cl9ndWlkKHJjbHNpZCkpOwogICAgICAgICAgICBTbGVlcCgxMDAwKTsKICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgfQogICAgICAgIFRSQUNFKCJyZWFkIG1hcnNoYWwgaWQgZnJvbSBwaXBlXG4iKTsKICAgICAgICBDbG9zZUhhbmRsZShoUGlwZSk7CiAgICAgICAgYnJlYWs7CiAgICB9CiAgICAKICAgIGlmICh0cmllcyA+PSBNQVhUUklFUykKICAgICAgICByZXR1cm4gRV9OT0lOVEVSRkFDRTsKICAgIAogICAgaHJlcyA9IENyZWF0ZVN0cmVhbU9uSEdsb2JhbCgwLFRSVUUsJnBTdG0pOwogICAgaWYgKGhyZXMpIHJldHVybiBocmVzOwogICAgaHJlcyA9IElTdHJlYW1fV3JpdGUocFN0bSxtYXJzaGFsYnVmZmVyLGJ1ZmZlcmxlbiwmcmVzKTsKICAgIGlmIChocmVzKSBnb3RvIG91dDsKICAgIHNlZWt0by51Lkxvd1BhcnQgPSAwO3NlZWt0by51LkhpZ2hQYXJ0ID0gMDsKICAgIGhyZXMgPSBJU3RyZWFtX1NlZWsocFN0bSxzZWVrdG8sU0VFS19TRVQsJm5ld3Bvcyk7CiAgICAKICAgIFRSQUNFKCJ1bm1hcnNoYWxsaW5nIGNsYXNzZmFjdG9yeVxuIik7CiAgICBocmVzID0gQ29Vbm1hcnNoYWxJbnRlcmZhY2UocFN0bSwmSUlEX0lDbGFzc0ZhY3RvcnkscHB2KTsKb3V0OgogICAgSVN0cmVhbV9SZWxlYXNlKHBTdG0pOwogICAgcmV0dXJuIGhyZXM7Cn0KCgpzdHJ1Y3QgbG9jYWxfc2VydmVyX3BhcmFtcwp7CiAgICBDTFNJRCBjbHNpZDsKICAgIElTdHJlYW0gKnN0cmVhbTsKICAgIEhBTkRMRSByZWFkeV9ldmVudDsKfTsKCi8qIEZJWE1FOiBzaG91bGQgY2FsbCB0byBycGNzcyBpbnN0ZWFkICovCnN0YXRpYyBEV09SRCBXSU5BUEkgbG9jYWxfc2VydmVyX3RocmVhZChMUFZPSUQgcGFyYW0pCnsKICAgIHN0cnVjdCBsb2NhbF9zZXJ2ZXJfcGFyYW1zICogbHNwID0gKHN0cnVjdCBsb2NhbF9zZXJ2ZXJfcGFyYW1zICopcGFyYW07CiAgICBIQU5ETEUJCWhQaXBlOwogICAgV0NIQVIgCQlwaXBlZm5bMTAwXTsKICAgIEhSRVNVTFQJCWhyZXM7CiAgICBJU3RyZWFtCQkqcFN0bSA9IGxzcC0+c3RyZWFtOwogICAgU1RBVFNURwkJc3RzdGc7CiAgICB1bnNpZ25lZCBjaGFyCSpidWZmZXI7CiAgICBpbnQgCQlidWZsZW47CiAgICBMQVJHRV9JTlRFR0VSCXNlZWt0bzsKICAgIFVMQVJHRV9JTlRFR0VSCW5ld3BvczsKICAgIFVMT05HCQlyZXM7CgogICAgVFJBQ0UoIlN0YXJ0aW5nIHRocmVhZGVyIGZvciAlcy5cbiIsZGVidWdzdHJfZ3VpZCgmbHNwLT5jbHNpZCkpOwoKICAgIGdldF9sb2NhbHNlcnZlcl9waXBlX25hbWUocGlwZWZuLCAmbHNwLT5jbHNpZCk7CgogICAgaFBpcGUgPSBDcmVhdGVOYW1lZFBpcGVXKCBwaXBlZm4sIFBJUEVfQUNDRVNTX0RVUExFWCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUElQRV9UWVBFX0JZVEV8UElQRV9XQUlULCBQSVBFX1VOTElNSVRFRF9JTlNUQU5DRVMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDQwOTYsIDQwOTYsIDUwMCAvKiAwLjUgc2Vjb25kIHRpbWVvdXQgKi8sIE5VTEwgKTsKCiAgICBTZXRFdmVudChsc3AtPnJlYWR5X2V2ZW50KTsKCiAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBsc3ApOwoKICAgIGlmIChoUGlwZSA9PSBJTlZBTElEX0hBTkRMRV9WQUxVRSkKICAgIHsKICAgICAgICBGSVhNRSgicGlwZSBjcmVhdGlvbiBmYWlsZWQgZm9yICVzLCBsZSBpcyAlZFxuIiwgZGVidWdzdHJfdyhwaXBlZm4pLCBHZXRMYXN0RXJyb3IoKSk7CiAgICAgICAgcmV0dXJuIDE7CiAgICB9CiAgICAKICAgIHdoaWxlICgxKSB7CiAgICAgICAgaWYgKCFDb25uZWN0TmFtZWRQaXBlKGhQaXBlLE5VTEwpICYmIEdldExhc3RFcnJvcigpICE9IEVSUk9SX1BJUEVfQ09OTkVDVEVEKSB7CiAgICAgICAgICAgIEVSUigiRmFpbHVyZSBkdXJpbmcgQ29ubmVjdE5hbWVkUGlwZSAlZCwgQUJPUlQhXG4iLEdldExhc3RFcnJvcigpKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgfQoKICAgICAgICBUUkFDRSgibWFyc2hhbGxpbmcgSUNsYXNzRmFjdG9yeSB0byBjbGllbnRcbiIpOwogICAgICAgIAogICAgICAgIGhyZXMgPSBJU3RyZWFtX1N0YXQocFN0bSwmc3RzdGcsMCk7CiAgICAgICAgaWYgKGhyZXMpIHJldHVybiBocmVzOwoKICAgICAgICBzZWVrdG8udS5Mb3dQYXJ0ID0gMDsKICAgICAgICBzZWVrdG8udS5IaWdoUGFydCA9IDA7CiAgICAgICAgaHJlcyA9IElTdHJlYW1fU2VlayhwU3RtLHNlZWt0byxTRUVLX1NFVCwmbmV3cG9zKTsKICAgICAgICBpZiAoaHJlcykgewogICAgICAgICAgICBGSVhNRSgiSVN0cmVhbV9TZWVrIGZhaWxlZCwgJXhcbiIsaHJlcyk7CiAgICAgICAgICAgIHJldHVybiBocmVzOwogICAgICAgIH0KCiAgICAgICAgYnVmbGVuID0gc3RzdGcuY2JTaXplLnUuTG93UGFydDsKICAgICAgICBidWZmZXIgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwwLGJ1Zmxlbik7CiAgICAgICAgCiAgICAgICAgaHJlcyA9IElTdHJlYW1fUmVhZChwU3RtLGJ1ZmZlcixidWZsZW4sJnJlcyk7CiAgICAgICAgaWYgKGhyZXMpIHsKICAgICAgICAgICAgRklYTUUoIlN0cmVhbSBSZWFkIGZhaWxlZCwgJXhcbiIsaHJlcyk7CiAgICAgICAgICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksMCxidWZmZXIpOwogICAgICAgICAgICByZXR1cm4gaHJlczsKICAgICAgICB9CiAgICAgICAgCiAgICAgICAgV3JpdGVGaWxlKGhQaXBlLGJ1ZmZlcixidWZsZW4sJnJlcyxOVUxMKTsKICAgICAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLDAsYnVmZmVyKTsKCiAgICAgICAgRmx1c2hGaWxlQnVmZmVycyhoUGlwZSk7CiAgICAgICAgRGlzY29ubmVjdE5hbWVkUGlwZShoUGlwZSk7CgogICAgICAgIFRSQUNFKCJkb25lIG1hcnNoYWxsaW5nIElDbGFzc0ZhY3RvcnlcbiIpOwogICAgfQogICAgQ2xvc2VIYW5kbGUoaFBpcGUpOwogICAgSVN0cmVhbV9SZWxlYXNlKHBTdG0pOwogICAgcmV0dXJuIDA7Cn0KCnZvaWQgUlBDX1N0YXJ0TG9jYWxTZXJ2ZXIoUkVGQ0xTSUQgY2xzaWQsIElTdHJlYW0gKnN0cmVhbSkKewogICAgRFdPUkQgdGlkOwogICAgSEFORExFIHRocmVhZCwgcmVhZHlfZXZlbnQ7CiAgICBzdHJ1Y3QgbG9jYWxfc2VydmVyX3BhcmFtcyAqbHNwID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIDAsIHNpemVvZigqbHNwKSk7CgogICAgbHNwLT5jbHNpZCA9ICpjbHNpZDsKICAgIGxzcC0+c3RyZWFtID0gc3RyZWFtOwogICAgSVN0cmVhbV9BZGRSZWYoc3RyZWFtKTsKICAgIGxzcC0+cmVhZHlfZXZlbnQgPSByZWFkeV9ldmVudCA9IENyZWF0ZUV2ZW50VyhOVUxMLCBGQUxTRSwgRkFMU0UsIE5VTEwpOwoKICAgIHRocmVhZCA9IENyZWF0ZVRocmVhZChOVUxMLCAwLCBsb2NhbF9zZXJ2ZXJfdGhyZWFkLCBsc3AsIDAsICZ0aWQpOwogICAgQ2xvc2VIYW5kbGUodGhyZWFkKTsKICAgIC8qIEZJWE1FOiBmYWlsdXJlIGhhbmRsaW5nICovCgogICAgV2FpdEZvclNpbmdsZU9iamVjdChyZWFkeV9ldmVudCwgSU5GSU5JVEUpOwogICAgQ2xvc2VIYW5kbGUocmVhZHlfZXZlbnQpOwp9Cg==