LyoKICoJUlBDIE1hbmFnZXIKICoKICogQ29weXJpZ2h0IDIwMDEgIE92ZSBL5XZlbiwgVHJhbnNHYW1pbmcgVGVjaG5vbG9naWVzCiAqIENvcHlyaWdodCAyMDAyICBNYXJjdXMgTWVpc3NuZXIKICogQ29weXJpZ2h0IDIwMDUgIE1pa2UgSGVhcm4sIFJvYiBTaGVhcm1hbiBmb3IgQ29kZVdlYXZlcnMKICoKICogVGhpcyBsaWJyYXJ5IGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vcgogKiBtb2RpZnkgaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljCiAqIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlcgogKiB2ZXJzaW9uIDIuMSBvZiB0aGUgTGljZW5zZSwgb3IgKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi4KICoKICogVGhpcyBsaWJyYXJ5IGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsCiAqIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mCiAqIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VCiAqIExlc3NlciBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMKICogTGljZW5zZSBhbG9uZyB3aXRoIHRoaXMgbGlicmFyeTsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZQogKiBGb3VuZGF0aW9uLCBJbmMuLCA1OSBUZW1wbGUgUGxhY2UsIFN1aXRlIDMzMCwgQm9zdG9uLCBNQSAgMDIxMTEtMTMwNyAgVVNBCiAqLwoKI2luY2x1ZGUgImNvbmZpZy5oIgoKI2luY2x1ZGUgPHN0ZGxpYi5oPgojaW5jbHVkZSA8c3RkYXJnLmg+CiNpbmNsdWRlIDxzdGRpby5oPgojaW5jbHVkZSA8c3RyaW5nLmg+CiNpbmNsdWRlIDxhc3NlcnQuaD4KCiNkZWZpbmUgQ09CSk1BQ1JPUwojZGVmaW5lIE5PTkFNRUxFU1NVTklPTgojZGVmaW5lIE5PTkFNRUxFU1NTVFJVQ1QKCiNpbmNsdWRlICJ3aW5kZWYuaCIKI2luY2x1ZGUgIndpbmJhc2UuaCIKI2luY2x1ZGUgIndpbnVzZXIuaCIKI2luY2x1ZGUgIndpbnN2Yy5oIgojaW5jbHVkZSAib2JqYmFzZS5oIgojaW5jbHVkZSAib2xlMi5oIgojaW5jbHVkZSAicnBjLmgiCiNpbmNsdWRlICJ3aW5lcnJvci5oIgojaW5jbHVkZSAid2lucmVnLmgiCiNpbmNsdWRlICJ3dHlwZXMuaCIKI2luY2x1ZGUgImV4Y3B0LmgiCiNpbmNsdWRlICJ3aW5lL3VuaWNvZGUuaCIKI2luY2x1ZGUgIndpbmUvZXhjZXB0aW9uLmgiCgojaW5jbHVkZSAiY29tcG9ial9wcml2YXRlLmgiCgojaW5jbHVkZSAid2luZS9kZWJ1Zy5oIgoKV0lORV9ERUZBVUxUX0RFQlVHX0NIQU5ORUwob2xlKTsKCnN0YXRpYyB2b2lkIF9fUlBDX1NUVUIgZGlzcGF0Y2hfcnBjKFJQQ19NRVNTQUdFICptc2cpOwoKLyogd2Ugb25seSB1c2Ugb25lIGZ1bmN0aW9uIHRvIGRpc3BhdGNoIGNhbGxzIGZvciBhbGwgbWV0aG9kcyAtIHdlIHVzZSB0aGUKICogUlBDX0lGX09MRSBmbGFnIHRvIHRlbGwgdGhlIFJQQyBydW50aW1lIHRoYXQgdGhpcyBpcyB0aGUgY2FzZSAqLwpzdGF0aWMgUlBDX0RJU1BBVENIX0ZVTkNUSU9OIHJwY19kaXNwYXRjaF90YWJsZVsxXSA9IHsgZGlzcGF0Y2hfcnBjIH07IC8qIChSTykgKi8Kc3RhdGljIFJQQ19ESVNQQVRDSF9UQUJMRSBycGNfZGlzcGF0Y2ggPSB7IDEsIHJwY19kaXNwYXRjaF90YWJsZSB9OyAvKiAoUk8pICovCgpzdGF0aWMgc3RydWN0IGxpc3QgcmVnaXN0ZXJlZF9pbnRlcmZhY2VzID0gTElTVF9JTklUKHJlZ2lzdGVyZWRfaW50ZXJmYWNlcyk7IC8qIChDUyBjc1JlZ0lmKSAqLwpzdGF0aWMgQ1JJVElDQUxfU0VDVElPTiBjc1JlZ0lmOwpzdGF0aWMgQ1JJVElDQUxfU0VDVElPTl9ERUJVRyBjc1JlZ0lmX2RlYnVnID0KewogICAgMCwgMCwgJmNzUmVnSWYsCiAgICB7ICZjc1JlZ0lmX2RlYnVnLlByb2Nlc3NMb2Nrc0xpc3QsICZjc1JlZ0lmX2RlYnVnLlByb2Nlc3NMb2Nrc0xpc3QgfSwKICAgICAgMCwgMCwgeyAoRFdPUkRfUFRSKShfX0ZJTEVfXyAiOiBkY29tIHJlZ2lzdGVyZWQgc2VydmVyIGludGVyZmFjZXMiKSB9Cn07CnN0YXRpYyBDUklUSUNBTF9TRUNUSU9OIGNzUmVnSWYgPSB7ICZjc1JlZ0lmX2RlYnVnLCAtMSwgMCwgMCwgMCwgMCB9OwoKc3RhdGljIFdDSEFSIHdzelBpcGVUcmFuc3BvcnRbXSA9IHsnbicsJ2MnLCdhJywnYycsJ24nLCdfJywnbicsJ3AnLDB9OwoKCnN0cnVjdCByZWdpc3RlcmVkX2lmCnsKICAgIHN0cnVjdCBsaXN0IGVudHJ5OwogICAgRFdPUkQgcmVmczsgLyogcmVmIGNvdW50ICovCiAgICBSUENfU0VSVkVSX0lOVEVSRkFDRSBJZjsgLyogaW50ZXJmYWNlIHJlZ2lzdGVyZWQgd2l0aCB0aGUgUlBDIHJ1bnRpbWUgKi8KfTsKCi8qIGdldCB0aGUgcGlwZSBlbmRwb2ludCBzcGVjaWZpZWQgb2YgdGhlIHNwZWNpZmllZCBhcGFydG1lbnQgKi8Kc3RhdGljIGlubGluZSB2b2lkIGdldF9ycGNfZW5kcG9pbnQoTFBXU1RSIGVuZHBvaW50LCBjb25zdCBPWElEICpveGlkKQp7CiAgICAvKiBGSVhNRTogc2hvdWxkIGdldCBlbmRwb2ludCBmcm9tIHJwY3NzICovCiAgICBzdGF0aWMgY29uc3QgV0NIQVIgd3N6RW5kcG9pbnRGb3JtYXRbXSA9IHsnXFwnLCdwJywnaScsJ3AnLCdlJywnXFwnLCdPJywnTCcsJ0UnLCdfJywnJScsJzAnLCc4JywnbCcsJ3gnLCclJywnMCcsJzgnLCdsJywneCcsMH07CiAgICB3c3ByaW50ZlcoZW5kcG9pbnQsIHdzekVuZHBvaW50Rm9ybWF0LCAoRFdPUkQpKCpveGlkID4+IDMyKSwoRFdPUkQpKm94aWQpOwp9Cgp0eXBlZGVmIHN0cnVjdAp7CiAgICBjb25zdCBJUnBjQ2hhbm5lbEJ1ZmZlclZ0YmwgKmxwVnRibDsKICAgIExPTkcgICAgICAgICAgICAgICAgICByZWZzOwp9IFJwY0NoYW5uZWxCdWZmZXI7Cgp0eXBlZGVmIHN0cnVjdAp7CiAgICBScGNDaGFubmVsQnVmZmVyICAgICAgIHN1cGVyOyAvKiBzdXBlcmNsYXNzICovCgogICAgUlBDX0JJTkRJTkdfSEFORExFICAgICBiaW5kOyAvKiBoYW5kbGUgdG8gdGhlIHJlbW90ZSBzZXJ2ZXIgKi8KfSBDbGllbnRScGNDaGFubmVsQnVmZmVyOwoKc3RydWN0IGRpc3BhdGNoX3BhcmFtcwp7CiAgICBSUENPTEVNRVNTQUdFICAgICAqbXNnOyAvKiBtZXNzYWdlICovCiAgICBJUnBjU3R1YkJ1ZmZlciAgICAqc3R1YjsgLyogc3R1YiBidWZmZXIsIGlmIGFwcGxpY2FibGUgKi8KICAgIElScGNDaGFubmVsQnVmZmVyICpjaGFuOyAvKiBzZXJ2ZXIgY2hhbm5lbCBidWZmZXIsIGlmIGFwcGxpY2FibGUgKi8KICAgIEhBTkRMRSAgICAgICAgICAgICBoYW5kbGU7IC8qIGhhbmRsZSB0aGF0IHdpbGwgYmVjb21lIHNpZ25hbGVkIHdoZW4gY2FsbCBmaW5pc2hlcyAqLwogICAgUlBDX1NUQVRVUyAgICAgICAgIHN0YXR1czsgLyogc3RhdHVzIChvdXQpICovCiAgICBIUkVTVUxUICAgICAgICAgICAgaHI7IC8qIGhyZXN1bHQgKG91dCkgKi8KfTsKCnN0YXRpYyBXSU5FX0VYQ0VQVElPTl9GSUxURVIob2xlX2ZpbHRlcikKewogICAgaWYgKEdldEV4Y2VwdGlvbkNvZGUoKSA9PSBFWENFUFRJT05fQUNDRVNTX1ZJT0xBVElPTiB8fAogICAgICAgIEdldEV4Y2VwdGlvbkNvZGUoKSA9PSBFWENFUFRJT05fUFJJVl9JTlNUUlVDVElPTikKICAgICAgICByZXR1cm4gRVhDRVBUSU9OX0NPTlRJTlVFX1NFQVJDSDsKICAgIHJldHVybiBFWENFUFRJT05fRVhFQ1VURV9IQU5ETEVSOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgUnBjQ2hhbm5lbEJ1ZmZlcl9RdWVyeUludGVyZmFjZShMUFJQQ0NIQU5ORUxCVUZGRVIgaWZhY2UsIFJFRklJRCByaWlkLCBMUFZPSUQgKnBwdikKewogICAgKnBwdiA9IE5VTEw7CiAgICBpZiAoSXNFcXVhbElJRChyaWlkLCZJSURfSVJwY0NoYW5uZWxCdWZmZXIpIHx8IElzRXF1YWxJSUQocmlpZCwmSUlEX0lVbmtub3duKSkKICAgIHsKICAgICAgICAqcHB2ID0gKExQVk9JRClpZmFjZTsKICAgICAgICBJVW5rbm93bl9BZGRSZWYoaWZhY2UpOwogICAgICAgIHJldHVybiBTX09LOwogICAgfQogICAgcmV0dXJuIEVfTk9JTlRFUkZBQ0U7Cn0KCnN0YXRpYyBVTE9ORyBXSU5BUEkgUnBjQ2hhbm5lbEJ1ZmZlcl9BZGRSZWYoTFBSUENDSEFOTkVMQlVGRkVSIGlmYWNlKQp7CiAgICBScGNDaGFubmVsQnVmZmVyICpUaGlzID0gKFJwY0NoYW5uZWxCdWZmZXIgKilpZmFjZTsKICAgIHJldHVybiBJbnRlcmxvY2tlZEluY3JlbWVudCgmVGhpcy0+cmVmcyk7Cn0KCnN0YXRpYyBVTE9ORyBXSU5BUEkgU2VydmVyUnBjQ2hhbm5lbEJ1ZmZlcl9SZWxlYXNlKExQUlBDQ0hBTk5FTEJVRkZFUiBpZmFjZSkKewogICAgUnBjQ2hhbm5lbEJ1ZmZlciAqVGhpcyA9IChScGNDaGFubmVsQnVmZmVyICopaWZhY2U7CiAgICBVTE9ORyByZWY7CgogICAgcmVmID0gSW50ZXJsb2NrZWREZWNyZW1lbnQoJlRoaXMtPnJlZnMpOwogICAgaWYgKHJlZikKICAgICAgICByZXR1cm4gcmVmOwoKICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIFRoaXMpOwogICAgcmV0dXJuIDA7Cn0KCnN0YXRpYyBVTE9ORyBXSU5BUEkgQ2xpZW50UnBjQ2hhbm5lbEJ1ZmZlcl9SZWxlYXNlKExQUlBDQ0hBTk5FTEJVRkZFUiBpZmFjZSkKewogICAgQ2xpZW50UnBjQ2hhbm5lbEJ1ZmZlciAqVGhpcyA9IChDbGllbnRScGNDaGFubmVsQnVmZmVyICopaWZhY2U7CiAgICBVTE9ORyByZWY7CgogICAgcmVmID0gSW50ZXJsb2NrZWREZWNyZW1lbnQoJlRoaXMtPnN1cGVyLnJlZnMpOwogICAgaWYgKHJlZikKICAgICAgICByZXR1cm4gcmVmOwoKICAgIFJwY0JpbmRpbmdGcmVlKCZUaGlzLT5iaW5kKTsKICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIFRoaXMpOwogICAgcmV0dXJuIDA7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBTZXJ2ZXJScGNDaGFubmVsQnVmZmVyX0dldEJ1ZmZlcihMUFJQQ0NIQU5ORUxCVUZGRVIgaWZhY2UsIFJQQ09MRU1FU1NBR0UqIG9sZW1zZywgUkVGSUlEIHJpaWQpCnsKICAgIFJwY0NoYW5uZWxCdWZmZXIgKlRoaXMgPSAoUnBjQ2hhbm5lbEJ1ZmZlciAqKWlmYWNlOwogICAgUlBDX01FU1NBR0UgKm1zZyA9IChSUENfTUVTU0FHRSAqKW9sZW1zZzsKICAgIFJQQ19TVEFUVVMgc3RhdHVzOwoKICAgIFRSQUNFKCIoJXApLT4oJXAsJXMpXG4iLCBUaGlzLCBvbGVtc2csIGRlYnVnc3RyX2d1aWQocmlpZCkpOwoKICAgIHN0YXR1cyA9IElfUnBjR2V0QnVmZmVyKG1zZyk7CgogICAgVFJBQ0UoIi0tICVsZFxuIiwgc3RhdHVzKTsKCiAgICByZXR1cm4gSFJFU1VMVF9GUk9NX1dJTjMyKHN0YXR1cyk7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBDbGllbnRScGNDaGFubmVsQnVmZmVyX0dldEJ1ZmZlcihMUFJQQ0NIQU5ORUxCVUZGRVIgaWZhY2UsIFJQQ09MRU1FU1NBR0UqIG9sZW1zZywgUkVGSUlEIHJpaWQpCnsKICAgIENsaWVudFJwY0NoYW5uZWxCdWZmZXIgKlRoaXMgPSAoQ2xpZW50UnBjQ2hhbm5lbEJ1ZmZlciAqKWlmYWNlOwogICAgUlBDX01FU1NBR0UgKm1zZyA9IChSUENfTUVTU0FHRSAqKW9sZW1zZzsKICAgIFJQQ19DTElFTlRfSU5URVJGQUNFICpjaWY7CiAgICBSUENfU1RBVFVTIHN0YXR1czsKCiAgICBUUkFDRSgiKCVwKS0+KCVwLCVzKVxuIiwgVGhpcywgb2xlbXNnLCBkZWJ1Z3N0cl9ndWlkKHJpaWQpKTsKCiAgICBjaWYgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgSEVBUF9aRVJPX01FTU9SWSwgc2l6ZW9mKFJQQ19DTElFTlRfSU5URVJGQUNFKSk7CiAgICBpZiAoIWNpZikKICAgICAgICByZXR1cm4gRV9PVVRPRk1FTU9SWTsKCiAgICBjaWYtPkxlbmd0aCA9IHNpemVvZihSUENfQ0xJRU5UX0lOVEVSRkFDRSk7CiAgICAvKiBSUEMgaW50ZXJmYWNlIElEID0gQ09NIGludGVyZmFjZSBJRCAqLwogICAgY2lmLT5JbnRlcmZhY2VJZC5TeW50YXhHVUlEID0gKnJpaWQ7CiAgICAvKiBDT00gb2JqZWN0cyBhbHdheXMgaGF2ZSBhIHZlcnNpb24gb2YgMC4wICovCiAgICBjaWYtPkludGVyZmFjZUlkLlN5bnRheFZlcnNpb24uTWFqb3JWZXJzaW9uID0gMDsKICAgIGNpZi0+SW50ZXJmYWNlSWQuU3ludGF4VmVyc2lvbi5NaW5vclZlcnNpb24gPSAwOwogICAgbXNnLT5ScGNJbnRlcmZhY2VJbmZvcm1hdGlvbiA9IGNpZjsKICAgIG1zZy0+SGFuZGxlID0gVGhpcy0+YmluZDsKICAgIAogICAgc3RhdHVzID0gSV9ScGNHZXRCdWZmZXIobXNnKTsKCiAgICBUUkFDRSgiLS0gJWxkXG4iLCBzdGF0dXMpOwoKICAgIHJldHVybiBIUkVTVUxUX0ZST01fV0lOMzIoc3RhdHVzKTsKfQoKLyogdGhpcyB0aHJlYWQgcnVucyBhbiBvdXRnb2luZyBSUEMgKi8Kc3RhdGljIERXT1JEIFdJTkFQSSBycGNfc2VuZHJlY2VpdmVfdGhyZWFkKExQVk9JRCBwYXJhbSkKewogICAgc3RydWN0IGRpc3BhdGNoX3BhcmFtcyAqZGF0YSA9IChzdHJ1Y3QgZGlzcGF0Y2hfcGFyYW1zICopIHBhcmFtOwogICAgCiAgICAvKiBGSVhNRTogdHJhcCBhbmQgcmV0aHJvdyBSUEMgZXhjZXB0aW9ucyBpbiBhcHAgdGhyZWFkICovCiAgICBkYXRhLT5zdGF0dXMgPSBJX1JwY1NlbmRSZWNlaXZlKChSUENfTUVTU0FHRSAqKWRhdGEtPm1zZyk7CgogICAgVFJBQ0UoImNvbXBsZXRlZCB3aXRoIHN0YXR1cyAweCVseFxuIiwgZGF0YS0+c3RhdHVzKTsKICAgIAogICAgcmV0dXJuIDA7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBScGNDaGFubmVsQnVmZmVyX1NlbmRSZWNlaXZlKExQUlBDQ0hBTk5FTEJVRkZFUiBpZmFjZSwgUlBDT0xFTUVTU0FHRSAqb2xlbXNnLCBVTE9ORyAqcHN0YXR1cykKewogICAgSFJFU1VMVCBociA9IFNfT0s7CiAgICBSUENfTUVTU0FHRSAqbXNnID0gKFJQQ19NRVNTQUdFICopb2xlbXNnOwogICAgUlBDX1NUQVRVUyBzdGF0dXM7CiAgICBEV09SRCBpbmRleDsKICAgIHN0cnVjdCBkaXNwYXRjaF9wYXJhbXMgKnBhcmFtczsKICAgIERXT1JEIHRpZDsKICAgIElScGNTdHViQnVmZmVyICpzdHViOwogICAgQVBBUlRNRU5UICphcHQ7CiAgICBJUElEIGlwaWQ7CgogICAgVFJBQ0UoIiglcCkgaU1ldGhvZD0lbGRcbiIsIG9sZW1zZywgb2xlbXNnLT5pTWV0aG9kKTsKCiAgICBwYXJhbXMgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgSEVBUF9aRVJPX01FTU9SWSwgc2l6ZW9mKCpwYXJhbXMpKTsKICAgIGlmICghcGFyYW1zKSByZXR1cm4gRV9PVVRPRk1FTU9SWTsKICAgIAogICAgcGFyYW1zLT5tc2cgPSBvbGVtc2c7CiAgICBwYXJhbXMtPnN0YXR1cyA9IFJQQ19TX09LOwogICAgcGFyYW1zLT5ociA9IFNfT0s7CgogICAgLyogTm90ZTogdGhpcyBpcyBhbiBvcHRpbWl6YXRpb24gaW4gdGhlIE1pY3Jvc29mdCBPTEUgcnVudGltZSB0aGF0IHdlIG5lZWQKICAgICAqIHRvIGNvcHksIGFzIHNob3duIGJ5IHRoZSB0ZXN0X25vX2NvdW5pbml0aWFsaXplX2NsaWVudCB0ZXN0LiB3aXRob3V0CiAgICAgKiBzaG9ydC1jaXJjdWl0aW5nIHRoZSBSUEMgcnVudGltZSBpbiB0aGUgY2FzZSBiZWxvdywgdGhlIHRlc3Qgd2lsbAogICAgICogZGVhZGxvY2sgb24gdGhlIGxvYWRlciBsb2NrIGR1ZSB0byB0aGUgUlBDIHJ1bnRpbWUgbmVlZGluZyB0byBjcmVhdGUKICAgICAqIGEgdGhyZWFkIHRvIHByb2Nlc3MgdGhlIFJQQyB3aGVuIHRoaXMgZnVuY3Rpb24gaXMgY2FsbGVkIGluZGlyZWN0bHkKICAgICAqIGZyb20gRGxsTWFpbiAqLwoKICAgIFJwY0JpbmRpbmdJbnFPYmplY3QobXNnLT5IYW5kbGUsICZpcGlkKTsKICAgIHN0dWIgPSBpcGlkX3RvX2FwdF9hbmRfc3R1YmJ1ZmZlcigmaXBpZCwgJmFwdCk7CiAgICBpZiAoYXB0ICYmIChhcHQtPm1vZGVsICYgQ09JTklUX0FQQVJUTUVOVFRIUkVBREVEKSkKICAgIHsKICAgICAgICBwYXJhbXMtPnN0dWIgPSBzdHViOwogICAgICAgIHBhcmFtcy0+Y2hhbiA9IE5VTEw7IC8qIEZJWE1FOiBwYXNzIHNlcnZlciBjaGFubmVsICovCiAgICAgICAgcGFyYW1zLT5oYW5kbGUgPSBDcmVhdGVFdmVudFcoTlVMTCwgRkFMU0UsIEZBTFNFLCBOVUxMKTsKCiAgICAgICAgVFJBQ0UoIkNhbGxpbmcgYXBhcnRtZW50IHRocmVhZCAweCUwOGx4Li4uXG4iLCBhcHQtPnRpZCk7CgogICAgICAgIFBvc3RNZXNzYWdlVyhhcHQtPndpbiwgRE1fRVhFQ1VURVJQQywgMCwgKExQQVJBTSlwYXJhbXMpOwogICAgfQogICAgZWxzZQogICAgewogICAgICAgIGlmIChzdHViKSBJUnBjU3R1YkJ1ZmZlcl9SZWxlYXNlKHN0dWIpOwoKICAgICAgICAvKiB3ZSB1c2UgYSBzZXBhcmF0ZSB0aHJlYWQgaGVyZSBiZWNhdXNlIHdlIG5lZWQgdG8gYmUgYWJsZSB0bwogICAgICAgICAqIHB1bXAgdGhlIG1lc3NhZ2UgbG9vcCBpbiB0aGUgYXBwbGljYXRpb24gdGhyZWFkOiBpZiB3ZSBkbyBub3QsCiAgICAgICAgICogYW55IHdpbmRvd3MgY3JlYXRlZCBieSB0aGlzIHRocmVhZCB3aWxsIGhhbmcgYW5kIFJQQ3MgdGhhdCB0cnkKICAgICAgICAgKiBhbmQgcmUtZW50ZXIgdGhpcyBTVEEgZnJvbSBhbiBpbmNvbWluZyBzZXJ2ZXIgdGhyZWFkIHdpbGwKICAgICAgICAgKiBkZWFkbG9jay4gSW5zdGFsbFNoaWVsZCBpcyBhbiBleGFtcGxlIG9mIHRoYXQuCiAgICAgICAgICovCiAgICAgICAgcGFyYW1zLT5oYW5kbGUgPSBDcmVhdGVUaHJlYWQoTlVMTCwgMCwgcnBjX3NlbmRyZWNlaXZlX3RocmVhZCwgcGFyYW1zLCAwLCAmdGlkKTsKICAgICAgICBpZiAoIXBhcmFtcy0+aGFuZGxlKQogICAgICAgIHsKICAgICAgICAgICAgRVJSKCJDb3VsZCBub3QgY3JlYXRlIFJwY1NlbmRSZWNlaXZlIHRocmVhZCwgZXJyb3IgJWx4XG4iLCBHZXRMYXN0RXJyb3IoKSk7CiAgICAgICAgICAgIGhyID0gRV9VTkVYUEVDVEVEOwogICAgICAgIH0KICAgIH0KICAgIGlmIChhcHQpIGFwYXJ0bWVudF9yZWxlYXNlKGFwdCk7CgogICAgaWYgKGhyID09IFNfT0spCiAgICAgICAgaHIgPSBDb1dhaXRGb3JNdWx0aXBsZUhhbmRsZXMoMCwgSU5GSU5JVEUsIDEsICZwYXJhbXMtPmhhbmRsZSwgJmluZGV4KTsKICAgIENsb3NlSGFuZGxlKHBhcmFtcy0+aGFuZGxlKTsKCiAgICBpZiAoaHIgPT0gU19PSykgaHIgPSBwYXJhbXMtPmhyOwoKICAgIHN0YXR1cyA9IHBhcmFtcy0+c3RhdHVzOwogICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgcGFyYW1zKTsKICAgIHBhcmFtcyA9IE5VTEw7CgogICAgaWYgKGhyKSByZXR1cm4gaHI7CiAgICAKICAgIGlmIChwc3RhdHVzKSAqcHN0YXR1cyA9IHN0YXR1czsKCiAgICBUUkFDRSgiUlBDIGNhbGwgc3RhdHVzOiAweCVseFxuIiwgc3RhdHVzKTsKICAgIGlmIChzdGF0dXMgPT0gUlBDX1NfT0spCiAgICAgICAgaHIgPSBTX09LOwogICAgZWxzZSBpZiAoc3RhdHVzID09IFJQQ19TX0NBTExfRkFJTEVEKQogICAgICAgIGhyID0gKihIUkVTVUxUICopb2xlbXNnLT5CdWZmZXI7CiAgICBlbHNlCiAgICAgICAgaHIgPSBIUkVTVUxUX0ZST01fV0lOMzIoc3RhdHVzKTsKCiAgICBUUkFDRSgiLS0gMHglMDhseFxuIiwgaHIpOwoKICAgIHJldHVybiBocjsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIFNlcnZlclJwY0NoYW5uZWxCdWZmZXJfRnJlZUJ1ZmZlcihMUFJQQ0NIQU5ORUxCVUZGRVIgaWZhY2UsIFJQQ09MRU1FU1NBR0UqIG9sZW1zZykKewogICAgUlBDX01FU1NBR0UgKm1zZyA9IChSUENfTUVTU0FHRSAqKW9sZW1zZzsKICAgIFJQQ19TVEFUVVMgc3RhdHVzOwoKICAgIFRSQUNFKCIoJXApXG4iLCBtc2cpOwoKICAgIHN0YXR1cyA9IElfUnBjRnJlZUJ1ZmZlcihtc2cpOwoKICAgIFRSQUNFKCItLSAlbGRcbiIsIHN0YXR1cyk7CgogICAgcmV0dXJuIEhSRVNVTFRfRlJPTV9XSU4zMihzdGF0dXMpOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgQ2xpZW50UnBjQ2hhbm5lbEJ1ZmZlcl9GcmVlQnVmZmVyKExQUlBDQ0hBTk5FTEJVRkZFUiBpZmFjZSwgUlBDT0xFTUVTU0FHRSogb2xlbXNnKQp7CiAgICBSUENfTUVTU0FHRSAqbXNnID0gKFJQQ19NRVNTQUdFICopb2xlbXNnOwogICAgUlBDX1NUQVRVUyBzdGF0dXM7CgogICAgVFJBQ0UoIiglcClcbiIsIG1zZyk7CgogICAgc3RhdHVzID0gSV9ScGNGcmVlQnVmZmVyKG1zZyk7CgogICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgbXNnLT5ScGNJbnRlcmZhY2VJbmZvcm1hdGlvbik7CiAgICBtc2ctPlJwY0ludGVyZmFjZUluZm9ybWF0aW9uID0gTlVMTDsKCiAgICBUUkFDRSgiLS0gJWxkXG4iLCBzdGF0dXMpOwoKICAgIHJldHVybiBIUkVTVUxUX0ZST01fV0lOMzIoc3RhdHVzKTsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIFJwY0NoYW5uZWxCdWZmZXJfR2V0RGVzdEN0eChMUFJQQ0NIQU5ORUxCVUZGRVIgaWZhY2UsIERXT1JEKiBwZHdEZXN0Q29udGV4dCwgdm9pZCoqIHBwdkRlc3RDb250ZXh0KQp7CiAgICBGSVhNRSgiKCVwLCVwKSwgc3R1YiFcbiIsIHBkd0Rlc3RDb250ZXh0LCBwcHZEZXN0Q29udGV4dCk7CiAgICByZXR1cm4gRV9GQUlMOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgUnBjQ2hhbm5lbEJ1ZmZlcl9Jc0Nvbm5lY3RlZChMUFJQQ0NIQU5ORUxCVUZGRVIgaWZhY2UpCnsKICAgIFRSQUNFKCIoKVxuIik7CiAgICAvKiBuYXRpdmUgZG9lcyBub3RoaW5nIHRvbyAqLwogICAgcmV0dXJuIFNfT0s7Cn0KCnN0YXRpYyBjb25zdCBJUnBjQ2hhbm5lbEJ1ZmZlclZ0YmwgQ2xpZW50UnBjQ2hhbm5lbEJ1ZmZlclZ0YmwgPQp7CiAgICBScGNDaGFubmVsQnVmZmVyX1F1ZXJ5SW50ZXJmYWNlLAogICAgUnBjQ2hhbm5lbEJ1ZmZlcl9BZGRSZWYsCiAgICBDbGllbnRScGNDaGFubmVsQnVmZmVyX1JlbGVhc2UsCiAgICBDbGllbnRScGNDaGFubmVsQnVmZmVyX0dldEJ1ZmZlciwKICAgIFJwY0NoYW5uZWxCdWZmZXJfU2VuZFJlY2VpdmUsCiAgICBDbGllbnRScGNDaGFubmVsQnVmZmVyX0ZyZWVCdWZmZXIsCiAgICBScGNDaGFubmVsQnVmZmVyX0dldERlc3RDdHgsCiAgICBScGNDaGFubmVsQnVmZmVyX0lzQ29ubmVjdGVkCn07CgpzdGF0aWMgY29uc3QgSVJwY0NoYW5uZWxCdWZmZXJWdGJsIFNlcnZlclJwY0NoYW5uZWxCdWZmZXJWdGJsID0KewogICAgUnBjQ2hhbm5lbEJ1ZmZlcl9RdWVyeUludGVyZmFjZSwKICAgIFJwY0NoYW5uZWxCdWZmZXJfQWRkUmVmLAogICAgU2VydmVyUnBjQ2hhbm5lbEJ1ZmZlcl9SZWxlYXNlLAogICAgU2VydmVyUnBjQ2hhbm5lbEJ1ZmZlcl9HZXRCdWZmZXIsCiAgICBScGNDaGFubmVsQnVmZmVyX1NlbmRSZWNlaXZlLAogICAgU2VydmVyUnBjQ2hhbm5lbEJ1ZmZlcl9GcmVlQnVmZmVyLAogICAgUnBjQ2hhbm5lbEJ1ZmZlcl9HZXREZXN0Q3R4LAogICAgUnBjQ2hhbm5lbEJ1ZmZlcl9Jc0Nvbm5lY3RlZAp9OwoKLyogcmV0dXJucyBhIGNoYW5uZWwgYnVmZmVyIGZvciBwcm94aWVzICovCkhSRVNVTFQgUlBDX0NyZWF0ZUNsaWVudENoYW5uZWwoY29uc3QgT1hJRCAqb3hpZCwgY29uc3QgSVBJRCAqaXBpZCwgSVJwY0NoYW5uZWxCdWZmZXIgKipjaGFuKQp7CiAgICBDbGllbnRScGNDaGFubmVsQnVmZmVyICpUaGlzOwogICAgV0NIQVIgICAgICAgICAgICAgICAgICAgZW5kcG9pbnRbMjAwXTsKICAgIFJQQ19CSU5ESU5HX0hBTkRMRSAgICAgIGJpbmQ7CiAgICBSUENfU1RBVFVTICAgICAgICAgICAgICBzdGF0dXM7CiAgICBMUFdTVFIgICAgICAgICAgICAgICAgICBzdHJpbmdfYmluZGluZzsKCiAgICAvKiBjb25uZWN0IHRvIHRoZSBhcGFydG1lbnQgbGlzdGVuZXIgdGhyZWFkICovCiAgICBnZXRfcnBjX2VuZHBvaW50KGVuZHBvaW50LCBveGlkKTsKCiAgICBUUkFDRSgicHJveHkgcGlwZTogY29ubmVjdGluZyB0byBlbmRwb2ludDogJXNcbiIsIGRlYnVnc3RyX3coZW5kcG9pbnQpKTsKCiAgICBzdGF0dXMgPSBScGNTdHJpbmdCaW5kaW5nQ29tcG9zZVcoCiAgICAgICAgTlVMTCwKICAgICAgICB3c3pQaXBlVHJhbnNwb3J0LAogICAgICAgIE5VTEwsCiAgICAgICAgZW5kcG9pbnQsCiAgICAgICAgTlVMTCwKICAgICAgICAmc3RyaW5nX2JpbmRpbmcpOwogICAgICAgIAogICAgaWYgKHN0YXR1cyA9PSBSUENfU19PSykKICAgIHsKICAgICAgICBzdGF0dXMgPSBScGNCaW5kaW5nRnJvbVN0cmluZ0JpbmRpbmdXKHN0cmluZ19iaW5kaW5nLCAmYmluZCk7CgogICAgICAgIGlmIChzdGF0dXMgPT0gUlBDX1NfT0spCiAgICAgICAgewogICAgICAgICAgICBJUElEIGlwaWQyID0gKmlwaWQ7IC8qIHdoeSBjYW4ndCBScGNCaW5kaW5nU2V0T2JqZWN0IHRha2UgYSBjb25zdD8gKi8KICAgICAgICAgICAgc3RhdHVzID0gUnBjQmluZGluZ1NldE9iamVjdChiaW5kLCAmaXBpZDIpOwogICAgICAgICAgICBpZiAoc3RhdHVzICE9IFJQQ19TX09LKQogICAgICAgICAgICAgICAgUnBjQmluZGluZ0ZyZWUoJmJpbmQpOwogICAgICAgIH0KCiAgICAgICAgUnBjU3RyaW5nRnJlZVcoJnN0cmluZ19iaW5kaW5nKTsKICAgIH0KCiAgICBpZiAoc3RhdHVzICE9IFJQQ19TX09LKQogICAgewogICAgICAgIEVSUigiQ291bGRuJ3QgZ2V0IGJpbmRpbmcgZm9yIGVuZHBvaW50ICVzLCBzdGF0dXMgPSAlbGRcbiIsIGRlYnVnc3RyX3coZW5kcG9pbnQpLCBzdGF0dXMpOwogICAgICAgIHJldHVybiBIUkVTVUxUX0ZST01fV0lOMzIoc3RhdHVzKTsKICAgIH0KCiAgICBUaGlzID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIDAsIHNpemVvZigqVGhpcykpOwogICAgaWYgKCFUaGlzKQogICAgewogICAgICAgIFJwY0JpbmRpbmdGcmVlKCZiaW5kKTsKICAgICAgICByZXR1cm4gRV9PVVRPRk1FTU9SWTsKICAgIH0KCiAgICBUaGlzLT5zdXBlci5scFZ0YmwgPSAmQ2xpZW50UnBjQ2hhbm5lbEJ1ZmZlclZ0Ymw7CiAgICBUaGlzLT5zdXBlci5yZWZzID0gMTsKICAgIFRoaXMtPmJpbmQgPSBiaW5kOwoKICAgICpjaGFuID0gKElScGNDaGFubmVsQnVmZmVyKilUaGlzOwoKICAgIHJldHVybiBTX09LOwp9CgpIUkVTVUxUIFJQQ19DcmVhdGVTZXJ2ZXJDaGFubmVsKElScGNDaGFubmVsQnVmZmVyICoqY2hhbikKewogICAgUnBjQ2hhbm5lbEJ1ZmZlciAqVGhpcyA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCAwLCBzaXplb2YoKlRoaXMpKTsKICAgIGlmICghVGhpcykKICAgICAgICByZXR1cm4gRV9PVVRPRk1FTU9SWTsKCiAgICBUaGlzLT5scFZ0YmwgPSAmU2VydmVyUnBjQ2hhbm5lbEJ1ZmZlclZ0Ymw7CiAgICBUaGlzLT5yZWZzID0gMTsKICAgIAogICAgKmNoYW4gPSAoSVJwY0NoYW5uZWxCdWZmZXIqKVRoaXM7CgogICAgcmV0dXJuIFNfT0s7Cn0KCgp2b2lkIFJQQ19FeGVjdXRlQ2FsbChzdHJ1Y3QgZGlzcGF0Y2hfcGFyYW1zICpwYXJhbXMpCnsKICAgIF9fVFJZCiAgICB7CiAgICAgICAgcGFyYW1zLT5ociA9IElScGNTdHViQnVmZmVyX0ludm9rZShwYXJhbXMtPnN0dWIsIHBhcmFtcy0+bXNnLCBwYXJhbXMtPmNoYW4pOwogICAgfQogICAgX19FWENFUFQob2xlX2ZpbHRlcikKICAgIHsKICAgICAgICBwYXJhbXMtPmhyID0gR2V0RXhjZXB0aW9uQ29kZSgpOwogICAgfQogICAgX19FTkRUUlkKICAgIElScGNTdHViQnVmZmVyX1JlbGVhc2UocGFyYW1zLT5zdHViKTsKICAgIGlmIChwYXJhbXMtPmhhbmRsZSkgU2V0RXZlbnQocGFyYW1zLT5oYW5kbGUpOwp9CgpzdGF0aWMgdm9pZCBfX1JQQ19TVFVCIGRpc3BhdGNoX3JwYyhSUENfTUVTU0FHRSAqbXNnKQp7CiAgICBzdHJ1Y3QgZGlzcGF0Y2hfcGFyYW1zICpwYXJhbXM7CiAgICBJUnBjU3R1YkJ1ZmZlciAgICAgKnN0dWI7CiAgICBBUEFSVE1FTlQgICAgICAgICAgKmFwdDsKICAgIElQSUQgICAgICAgICAgICAgICAgaXBpZDsKCiAgICBScGNCaW5kaW5nSW5xT2JqZWN0KG1zZy0+SGFuZGxlLCAmaXBpZCk7CgogICAgVFJBQ0UoImlwaWQgPSAlcywgaU1ldGhvZCA9ICVkXG4iLCBkZWJ1Z3N0cl9ndWlkKCZpcGlkKSwgbXNnLT5Qcm9jTnVtKTsKCiAgICBwYXJhbXMgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgSEVBUF9aRVJPX01FTU9SWSwgc2l6ZW9mKCpwYXJhbXMpKTsKICAgIGlmICghcGFyYW1zKSByZXR1cm4gUnBjUmFpc2VFeGNlcHRpb24oRV9PVVRPRk1FTU9SWSk7CgogICAgc3R1YiA9IGlwaWRfdG9fYXB0X2FuZF9zdHViYnVmZmVyKCZpcGlkLCAmYXB0KTsKICAgIGlmICghYXB0IHx8ICFzdHViKQogICAgewogICAgICAgIGlmIChhcHQpIGFwYXJ0bWVudF9yZWxlYXNlKGFwdCk7CiAgICAgICAgRVJSKCJubyBhcGFydG1lbnQgZm91bmQgZm9yIGlwaWQgJXNcbiIsIGRlYnVnc3RyX2d1aWQoJmlwaWQpKTsKICAgICAgICByZXR1cm4gUnBjUmFpc2VFeGNlcHRpb24oUlBDX0VfRElTQ09OTkVDVEVEKTsKICAgIH0KCiAgICBwYXJhbXMtPm1zZyA9IChSUENPTEVNRVNTQUdFICopbXNnOwogICAgcGFyYW1zLT5zdHViID0gc3R1YjsKICAgIHBhcmFtcy0+Y2hhbiA9IE5VTEw7IC8qIEZJWE1FOiBwYXNzIHNlcnZlciBjaGFubmVsICovCiAgICBwYXJhbXMtPnN0YXR1cyA9IFJQQ19TX09LOwoKICAgIC8qIE5vdGU6IHRoaXMgaXMgdGhlIGltcG9ydGFudCBkaWZmZXJlbmNlIGJldHdlZW4gU1RBcyBhbmQgTVRBcyAtIHdlCiAgICAgKiBhbHdheXMgZXhlY3V0ZSBSUENzIHRvIFNUQXMgaW4gdGhlIHRocmVhZCB0aGF0IG9yaWdpbmFsbHkgY3JlYXRlZCB0aGUKICAgICAqIGFwYXJ0bWVudCAoaS5lLiB0aGUgb25lIHRoYXQgcHVtcHMgbWVzc2FnZXMgdG8gdGhlIHdpbmRvdykgKi8KICAgIGlmIChhcHQtPm1vZGVsICYgQ09JTklUX0FQQVJUTUVOVFRIUkVBREVEKQogICAgewogICAgICAgIHBhcmFtcy0+aGFuZGxlID0gQ3JlYXRlRXZlbnRXKE5VTEwsIEZBTFNFLCBGQUxTRSwgTlVMTCk7CgogICAgICAgIFRSQUNFKCJDYWxsaW5nIGFwYXJ0bWVudCB0aHJlYWQgMHglMDhseC4uLlxuIiwgYXB0LT50aWQpOwoKICAgICAgICBQb3N0TWVzc2FnZVcoYXB0LT53aW4sIERNX0VYRUNVVEVSUEMsIDAsIChMUEFSQU0pcGFyYW1zKTsKICAgICAgICBXYWl0Rm9yU2luZ2xlT2JqZWN0KHBhcmFtcy0+aGFuZGxlLCBJTkZJTklURSk7CiAgICAgICAgQ2xvc2VIYW5kbGUocGFyYW1zLT5oYW5kbGUpOwogICAgfQogICAgZWxzZQogICAgICAgIFJQQ19FeGVjdXRlQ2FsbChwYXJhbXMpOwoKICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIHBhcmFtcyk7CgogICAgYXBhcnRtZW50X3JlbGVhc2UoYXB0KTsKfQoKLyogc3R1YiByZWdpc3RyYXRpb24gKi8KSFJFU1VMVCBSUENfUmVnaXN0ZXJJbnRlcmZhY2UoUkVGSUlEIHJpaWQpCnsKICAgIHN0cnVjdCByZWdpc3RlcmVkX2lmICpyaWY7CiAgICBCT09MIGZvdW5kID0gRkFMU0U7CiAgICBIUkVTVUxUIGhyID0gU19PSzsKICAgIAogICAgVFJBQ0UoIiglcylcbiIsIGRlYnVnc3RyX2d1aWQocmlpZCkpOwoKICAgIEVudGVyQ3JpdGljYWxTZWN0aW9uKCZjc1JlZ0lmKTsKICAgIExJU1RfRk9SX0VBQ0hfRU5UUlkocmlmLCAmcmVnaXN0ZXJlZF9pbnRlcmZhY2VzLCBzdHJ1Y3QgcmVnaXN0ZXJlZF9pZiwgZW50cnkpCiAgICB7CiAgICAgICAgaWYgKElzRXF1YWxHVUlEKCZyaWYtPklmLkludGVyZmFjZUlkLlN5bnRheEdVSUQsIHJpaWQpKQogICAgICAgIHsKICAgICAgICAgICAgcmlmLT5yZWZzKys7CiAgICAgICAgICAgIGZvdW5kID0gVFJVRTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgfQogICAgfQogICAgaWYgKCFmb3VuZCkKICAgIHsKICAgICAgICBUUkFDRSgiQ3JlYXRpbmcgbmV3IGludGVyZmFjZVxuIik7CgogICAgICAgIHJpZiA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCBIRUFQX1pFUk9fTUVNT1JZLCBzaXplb2YoKnJpZikpOwogICAgICAgIGlmIChyaWYpCiAgICAgICAgewogICAgICAgICAgICBSUENfU1RBVFVTIHN0YXR1czsKCiAgICAgICAgICAgIHJpZi0+cmVmcyA9IDE7CiAgICAgICAgICAgIHJpZi0+SWYuTGVuZ3RoID0gc2l6ZW9mKFJQQ19TRVJWRVJfSU5URVJGQUNFKTsKICAgICAgICAgICAgLyogUlBDIGludGVyZmFjZSBJRCA9IENPTSBpbnRlcmZhY2UgSUQgKi8KICAgICAgICAgICAgcmlmLT5JZi5JbnRlcmZhY2VJZC5TeW50YXhHVUlEID0gKnJpaWQ7CiAgICAgICAgICAgIHJpZi0+SWYuRGlzcGF0Y2hUYWJsZSA9ICZycGNfZGlzcGF0Y2g7CiAgICAgICAgICAgIC8qIGFsbCBvdGhlciBmaWVsZHMgYXJlIDAsIGluY2x1ZGluZyB0aGUgdmVyc2lvbiBhc0NPTSBvYmplY3RzCiAgICAgICAgICAgICAqIGFsd2F5cyBoYXZlIGEgdmVyc2lvbiBvZiAwLjAgKi8KICAgICAgICAgICAgc3RhdHVzID0gUnBjU2VydmVyUmVnaXN0ZXJJZkV4KAogICAgICAgICAgICAgICAgKFJQQ19JRl9IQU5ETEUpJnJpZi0+SWYsCiAgICAgICAgICAgICAgICBOVUxMLCBOVUxMLAogICAgICAgICAgICAgICAgUlBDX0lGX09MRSB8IFJQQ19JRl9BVVRPTElTVEVOLAogICAgICAgICAgICAgICAgUlBDX0NfTElTVEVOX01BWF9DQUxMU19ERUZBVUxULAogICAgICAgICAgICAgICAgTlVMTCk7CiAgICAgICAgICAgIGlmIChzdGF0dXMgPT0gUlBDX1NfT0spCiAgICAgICAgICAgICAgICBsaXN0X2FkZF90YWlsKCZyZWdpc3RlcmVkX2ludGVyZmFjZXMsICZyaWYtPmVudHJ5KTsKICAgICAgICAgICAgZWxzZQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBFUlIoIlJwY1NlcnZlclJlZ2lzdGVySWZFeCBmYWlsZWQgd2l0aCBlcnJvciAlbGRcbiIsIHN0YXR1cyk7CiAgICAgICAgICAgICAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCByaWYpOwogICAgICAgICAgICAgICAgaHIgPSBIUkVTVUxUX0ZST01fV0lOMzIoc3RhdHVzKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBlbHNlCiAgICAgICAgICAgIGhyID0gRV9PVVRPRk1FTU9SWTsKICAgIH0KICAgIExlYXZlQ3JpdGljYWxTZWN0aW9uKCZjc1JlZ0lmKTsKICAgIHJldHVybiBocjsKfQoKLyogc3R1YiB1bnJlZ2lzdHJhdGlvbiAqLwp2b2lkIFJQQ19VbnJlZ2lzdGVySW50ZXJmYWNlKFJFRklJRCByaWlkKQp7CiAgICBzdHJ1Y3QgcmVnaXN0ZXJlZF9pZiAqcmlmOwogICAgRW50ZXJDcml0aWNhbFNlY3Rpb24oJmNzUmVnSWYpOwogICAgTElTVF9GT1JfRUFDSF9FTlRSWShyaWYsICZyZWdpc3RlcmVkX2ludGVyZmFjZXMsIHN0cnVjdCByZWdpc3RlcmVkX2lmLCBlbnRyeSkKICAgIHsKICAgICAgICBpZiAoSXNFcXVhbEdVSUQoJnJpZi0+SWYuSW50ZXJmYWNlSWQuU3ludGF4R1VJRCwgcmlpZCkpCiAgICAgICAgewogICAgICAgICAgICBpZiAoIS0tcmlmLT5yZWZzKQogICAgICAgICAgICB7CiNpZiAwIC8qIHRoaXMgaXMgYSBzdHViIGluIGJ1aWx0aW4gYW5kIHNwYW1zIHRoZSBjb25zb2xlIHdpdGggRklYTUUncyAqLwogICAgICAgICAgICAgICAgSUlEIGlpZCA9ICpyaWlkOyAvKiBScGNTZXJ2ZXJVbnJlZ2lzdGVySWYgZG9lc24ndCB0YWtlIGNvbnN0IElJRCAqLwogICAgICAgICAgICAgICAgUnBjU2VydmVyVW5yZWdpc3RlcklmKChSUENfSUZfSEFORExFKSZyaWYtPklmLCAmaWlkLCAwKTsKICAgICAgICAgICAgICAgIGxpc3RfcmVtb3ZlKCZyaWYtPmVudHJ5KTsKICAgICAgICAgICAgICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIHJpZik7CiNlbmRpZgogICAgICAgICAgICB9CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIH0KICAgIH0KICAgIExlYXZlQ3JpdGljYWxTZWN0aW9uKCZjc1JlZ0lmKTsKfQoKLyogbWFrZSB0aGUgYXBhcnRtZW50IHJlYWNoYWJsZSBieSBvdGhlciB0aHJlYWRzIGFuZCBwcm9jZXNzZXMgYW5kIGNyZWF0ZSB0aGUKICogSVJlbVVua25vd24gb2JqZWN0ICovCnZvaWQgUlBDX1N0YXJ0UmVtb3Rpbmcoc3RydWN0IGFwYXJ0bWVudCAqYXB0KQp7CiAgICBpZiAoIUludGVybG9ja2VkRXhjaGFuZ2UoJmFwdC0+cmVtb3Rpbmdfc3RhcnRlZCwgVFJVRSkpCiAgICB7CiAgICAgICAgV0NIQVIgZW5kcG9pbnRbMjAwXTsKICAgICAgICBSUENfU1RBVFVTIHN0YXR1czsKCiAgICAgICAgZ2V0X3JwY19lbmRwb2ludChlbmRwb2ludCwgJmFwdC0+b3hpZCk7CiAgICAKICAgICAgICBzdGF0dXMgPSBScGNTZXJ2ZXJVc2VQcm90c2VxRXBXKAogICAgICAgICAgICB3c3pQaXBlVHJhbnNwb3J0LAogICAgICAgICAgICBSUENfQ19QUk9UU0VRX01BWF9SRVFTX0RFRkFVTFQsCiAgICAgICAgICAgIGVuZHBvaW50LAogICAgICAgICAgICBOVUxMKTsKICAgICAgICBpZiAoc3RhdHVzICE9IFJQQ19TX09LKQogICAgICAgICAgICBFUlIoIkNvdWxkbid0IHJlZ2lzdGVyIGVuZHBvaW50ICVzXG4iLCBkZWJ1Z3N0cl93KGVuZHBvaW50KSk7CgogICAgICAgIC8qIEZJWE1FOiBtb3ZlIHJlbW90ZSB1bmtub3duIGV4cG9ydGluZyBpbnRvIHRoaXMgZnVuY3Rpb24gKi8KICAgIH0KICAgIHN0YXJ0X2FwYXJ0bWVudF9yZW1vdGVfdW5rbm93bigpOwp9CgoKc3RhdGljIEhSRVNVTFQgY3JlYXRlX3NlcnZlcihSRUZDTFNJRCByY2xzaWQpCnsKICAgIHN0YXRpYyBjb25zdCBXQ0hBUiAgd3N6TG9jYWxTZXJ2ZXIzMltdID0geyAnTCcsJ28nLCdjJywnYScsJ2wnLCdTJywnZScsJ3InLCd2JywnZScsJ3InLCczJywnMicsMCB9OwogICAgc3RhdGljIGNvbnN0IFdDSEFSICBlbWJlZGRpbmdbXSA9IHsgJyAnLCAnLScsJ0UnLCdtJywnYicsJ2UnLCdkJywnZCcsJ2knLCduJywnZycsMCB9OwogICAgSEtFWSAgICAgICAgICAgICAgICBrZXk7CiAgICBIUkVTVUxUICAgICAgICAgICAgIGhyZXM7CiAgICBXQ0hBUiAgICAgICAgICAgICAgIGNvbW1hbmRbTUFYX1BBVEgrc2l6ZW9mKGVtYmVkZGluZykvc2l6ZW9mKFdDSEFSKV07CiAgICBEV09SRCAgICAgICAgICAgICAgIHNpemUgPSAoTUFYX1BBVEgrMSkgKiBzaXplb2YoV0NIQVIpOwogICAgU1RBUlRVUElORk9XICAgICAgICBzaW5mbzsKICAgIFBST0NFU1NfSU5GT1JNQVRJT04gcGluZm87CgogICAgaHJlcyA9IENPTV9PcGVuS2V5Rm9yQ0xTSUQocmNsc2lkLCB3c3pMb2NhbFNlcnZlcjMyLCBLRVlfUkVBRCwgJmtleSk7CiAgICBpZiAoRkFJTEVEKGhyZXMpKSB7CiAgICAgICAgRVJSKCJjbGFzcyAlcyBub3QgcmVnaXN0ZXJlZFxuIiwgZGVidWdzdHJfZ3VpZChyY2xzaWQpKTsKICAgICAgICByZXR1cm4gaHJlczsKICAgIH0KCiAgICBocmVzID0gUmVnUXVlcnlWYWx1ZUV4VyhrZXksIE5VTEwsIE5VTEwsIE5VTEwsIChMUEJZVEUpY29tbWFuZCwgJnNpemUpOwogICAgUmVnQ2xvc2VLZXkoa2V5KTsKICAgIGlmIChocmVzKSB7CiAgICAgICAgV0FSTigiTm8gZGVmYXVsdCB2YWx1ZSBmb3IgTG9jYWxTZXJ2ZXIzMiBrZXlcbiIpOwogICAgICAgIHJldHVybiBSRUdEQl9FX0NMQVNTTk9UUkVHOyAvKiBGSVhNRTogY2hlY2sgcmV0dmFsICovCiAgICB9CgogICAgbWVtc2V0KCZzaW5mbywwLHNpemVvZihzaW5mbykpOwogICAgc2luZm8uY2IgPSBzaXplb2Yoc2luZm8pOwoKICAgIC8qIEVYRSBzZXJ2ZXJzIGFyZSBzdGFydGVkIHdpdGggdGhlIC1FbWJlZGRpbmcgc3dpdGNoLiAqLwoKICAgIHN0cmNhdFcoY29tbWFuZCwgZW1iZWRkaW5nKTsKCiAgICBUUkFDRSgiYWN0aXZhdGluZyBsb2NhbCBzZXJ2ZXIgJXMgZm9yICVzXG4iLCBkZWJ1Z3N0cl93KGNvbW1hbmQpLCBkZWJ1Z3N0cl9ndWlkKHJjbHNpZCkpOwoKICAgIC8qIEZJWE1FOiBXaW4yMDAzIHN1cHBvcnRzIGEgU2VydmVyRXhlY3V0YWJsZSB2YWx1ZSB0aGF0IGlzIHBhc3NlZCBpbnRvCiAgICAgKiBDcmVhdGVQcm9jZXNzICovCiAgICBpZiAoIUNyZWF0ZVByb2Nlc3NXKE5VTEwsIGNvbW1hbmQsIE5VTEwsIE5VTEwsIEZBTFNFLCAwLCBOVUxMLCBOVUxMLCAmc2luZm8sICZwaW5mbykpIHsKICAgICAgICBXQVJOKCJmYWlsZWQgdG8gcnVuIGxvY2FsIHNlcnZlciAlc1xuIiwgZGVidWdzdHJfdyhjb21tYW5kKSk7CiAgICAgICAgcmV0dXJuIEhSRVNVTFRfRlJPTV9XSU4zMihHZXRMYXN0RXJyb3IoKSk7CiAgICB9CiAgICBDbG9zZUhhbmRsZShwaW5mby5oUHJvY2Vzcyk7CiAgICBDbG9zZUhhbmRsZShwaW5mby5oVGhyZWFkKTsKCiAgICByZXR1cm4gU19PSzsKfQoKLyoKICogc3RhcnRfbG9jYWxfc2VydmljZSgpICAtIHN0YXJ0IGEgc2VydmljZSBnaXZlbiBpdHMgbmFtZSBhbmQgcGFyYW1ldGVycwogKi8Kc3RhdGljIERXT1JEIHN0YXJ0X2xvY2FsX3NlcnZpY2UoTFBDV1NUUiBuYW1lLCBEV09SRCBudW0sIExQV1NUUiAqcGFyYW1zKQp7CiAgICBTQ19IQU5ETEUgaGFuZGxlLCBoc3ZjOwogICAgRFdPUkQgICAgIHIgPSBFUlJPUl9GVU5DVElPTl9GQUlMRUQ7CgogICAgVFJBQ0UoIlN0YXJ0aW5nIHNlcnZpY2UgJXMgJWxkIHBhcmFtc1xuIiwgZGVidWdzdHJfdyhuYW1lKSwgbnVtKTsKCiAgICBoYW5kbGUgPSBPcGVuU0NNYW5hZ2VyVyhOVUxMLCBOVUxMLCBTQ19NQU5BR0VSX0FMTF9BQ0NFU1MpOwogICAgaWYgKCFoYW5kbGUpCiAgICAgICAgcmV0dXJuIHI7CiAgICBoc3ZjID0gT3BlblNlcnZpY2VXKGhhbmRsZSwgbmFtZSwgU0NfTUFOQUdFUl9BTExfQUNDRVNTKTsKICAgIGlmIChoc3ZjKQogICAgewogICAgICAgIGlmKFN0YXJ0U2VydmljZVcoaHN2YywgbnVtLCAoTFBDV1NUUiopcGFyYW1zKSkKICAgICAgICAgICAgciA9IEVSUk9SX1NVQ0NFU1M7CiAgICAgICAgZWxzZQogICAgICAgICAgICByID0gR2V0TGFzdEVycm9yKCk7CiAgICAgICAgaWYgKHIgPT0gRVJST1JfU0VSVklDRV9BTFJFQURZX1JVTk5JTkcpCiAgICAgICAgICAgIHIgPSBFUlJPUl9TVUNDRVNTOwogICAgICAgIENsb3NlU2VydmljZUhhbmRsZShoc3ZjKTsKICAgIH0KICAgIENsb3NlU2VydmljZUhhbmRsZShoYW5kbGUpOwoKICAgIFRSQUNFKCJTdGFydFNlcnZpY2UgcmV0dXJuZWQgZXJyb3IgJWxkICglcylcbiIsIHIsIHI/Im9rIjoiZmFpbGVkIik7CgogICAgcmV0dXJuIHI7Cn0KCi8qCiAqIGNyZWF0ZV9sb2NhbF9zZXJ2aWNlKCkgIC0gc3RhcnQgYSBDT00gc2VydmVyIGluIGEgc2VydmljZQogKgogKiAgIFRvIHN0YXJ0IGEgTG9jYWwgU2VydmljZSwgd2UgcmVhZCB0aGUgQXBwSUQgdmFsdWUgdW5kZXIKICogdGhlIGNsYXNzJ3MgQ0xTSUQga2V5LCB0aGVuIG9wZW4gdGhlIEhLQ1JcXEFwcElkIGtleSBzcGVjaWZpZWQKICogdGhlcmUgYW5kIGNoZWNrIGZvciBhIExvY2FsU2VydmljZSB2YWx1ZS4KICoKICogTm90ZTogIExvY2FsIFNlcnZpY2VzIGFyZSBub3Qgc3VwcG9ydGVkIHVuZGVyIFdpbmRvd3MgOXgKICovCnN0YXRpYyBIUkVTVUxUIGNyZWF0ZV9sb2NhbF9zZXJ2aWNlKFJFRkNMU0lEIHJjbHNpZCkKewogICAgSFJFU1VMVCBocmVzOwogICAgV0NIQVIgYnVmW0NIQVJTX0lOX0dVSURdLCBrZXluYW1lWzUwXTsKICAgIHN0YXRpYyBjb25zdCBXQ0hBUiBzekFwcElkW10gPSB7ICdBJywncCcsJ3AnLCdJJywnZCcsMCB9OwogICAgc3RhdGljIGNvbnN0IFdDSEFSIHN6QXBwSWRLZXlbXSA9IHsgJ0EnLCdwJywncCcsJ0knLCdkJywnXFwnLDAgfTsKICAgIHN0YXRpYyBjb25zdCBXQ0hBUiBzekxvY2FsU2VydmljZVtdID0geyAnTCcsJ28nLCdjJywnYScsJ2wnLCdTJywnZScsJ3InLCd2JywnaScsJ2MnLCdlJywwIH07CiAgICBzdGF0aWMgY29uc3QgV0NIQVIgc3pTZXJ2aWNlUGFyYW1zW10gPSB7J1MnLCdlJywncicsJ3YnLCdpJywnYycsJ2UnLCdQJywnYScsJ3InLCdhJywnbScsJ3MnLDB9OwogICAgSEtFWSBoa2V5OwogICAgTE9ORyByOwogICAgRFdPUkQgdHlwZSwgc3o7CgogICAgVFJBQ0UoIkF0dGVtcHRpbmcgdG8gc3RhcnQgTG9jYWwgc2VydmljZSBmb3IgJXNcbiIsIGRlYnVnc3RyX2d1aWQocmNsc2lkKSk7CgogICAgLyogcmVhZCB0aGUgQXBwSUQgdmFsdWUgdW5kZXIgdGhlIGNsYXNzJ3Mga2V5ICovCiAgICBocmVzID0gQ09NX09wZW5LZXlGb3JDTFNJRChyY2xzaWQsIHN6QXBwSWQsIEtFWV9SRUFELCAmaGtleSk7CiAgICBpZiAoRkFJTEVEKGhyZXMpKQogICAgICAgIHJldHVybiBocmVzOwogICAgc3ogPSBzaXplb2YgYnVmOwogICAgciA9IFJlZ1F1ZXJ5VmFsdWVFeFcoaGtleSwgTlVMTCwgTlVMTCwgJnR5cGUsIChMUEJZVEUpYnVmLCAmc3opOwogICAgUmVnQ2xvc2VLZXkoaGtleSk7CiAgICBpZiAociE9RVJST1JfU1VDQ0VTUyB8fCB0eXBlIT1SRUdfU1opCiAgICAgICAgcmV0dXJuIGhyZXM7CgogICAgLyogcmVhZCB0aGUgTG9jYWxTZXJ2aWNlIGFuZCBTZXJ2aWNlUGFyYW1ldGVycyB2YWx1ZXMgZnJvbSB0aGUgQXBwSUQga2V5ICovCiAgICBzdHJjcHlXKGtleW5hbWUsIHN6QXBwSWRLZXkpOwogICAgc3RyY2F0VyhrZXluYW1lLCBidWYpOwogICAgciA9IFJlZ09wZW5LZXlFeFcoSEtFWV9DTEFTU0VTX1JPT1QsIGtleW5hbWUsIDAsIEtFWV9SRUFELCAmaGtleSk7CiAgICBpZiAociE9RVJST1JfU1VDQ0VTUykKICAgICAgICByZXR1cm4gaHJlczsKICAgIHN6ID0gc2l6ZW9mIGJ1ZjsKICAgIHIgPSBSZWdRdWVyeVZhbHVlRXhXKGhrZXksIHN6TG9jYWxTZXJ2aWNlLCBOVUxMLCAmdHlwZSwgKExQQllURSlidWYsICZzeik7CiAgICBpZiAocj09RVJST1JfU1VDQ0VTUyAmJiB0eXBlPT1SRUdfU1opCiAgICB7CiAgICAgICAgRFdPUkQgbnVtX2FyZ3MgPSAwOwogICAgICAgIExQV1NUUiBhcmdzWzFdID0geyBOVUxMIH07CgogICAgICAgIC8qCiAgICAgICAgICogRklYTUU6IEknbSBub3QgcmVhbGx5IHN1cmUgaG93IHRvIGRlYWwgd2l0aCB0aGUgc2VydmljZSBwYXJhbWV0ZXJzLgogICAgICAgICAqICAgICAgICBJIHN1c3BlY3QgdGhhdCB0aGUgc3RyaW5nIHJldHVybmVkIGZyb20gUmVnUXVlcnlWYWx1ZUV4VwogICAgICAgICAqICAgICAgICBzaG91bGQgYmUgc3BsaXQgaW50byBhIG51bWJlciBvZiBhcmd1bWVudHMgYnkgc3BhY2VzLgogICAgICAgICAqICAgICAgICBJdCB3b3VsZCBtYWtlIG1vcmUgc2Vuc2UgaWYgU2VydmljZVBhcmFtcyBjb250YWluZWQgYQogICAgICAgICAqICAgICAgICBSRUdfTVVMVElfU1ogaGVyZSwgYnV0IGl0J3MgYSBSRUdfU1ogZm9yIHRoZSBzZXJ2aWNlcwogICAgICAgICAqICAgICAgICB0aGF0IEknbSBpbnRlcmVzdGVkIGluIGZvciB0aGUgbW9tZW50LgogICAgICAgICAqLwogICAgICAgIHIgPSBSZWdRdWVyeVZhbHVlRXhXKGhrZXksIHN6U2VydmljZVBhcmFtcywgTlVMTCwgJnR5cGUsIE5VTEwsICZzeik7CiAgICAgICAgaWYgKHIgPT0gRVJST1JfU1VDQ0VTUyAmJiB0eXBlID09IFJFR19TWiAmJiBzeikKICAgICAgICB7CiAgICAgICAgICAgIGFyZ3NbMF0gPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSxIRUFQX1pFUk9fTUVNT1JZLHN6KTsKICAgICAgICAgICAgbnVtX2FyZ3MrKzsKICAgICAgICAgICAgUmVnUXVlcnlWYWx1ZUV4Vyhoa2V5LCBzelNlcnZpY2VQYXJhbXMsIE5VTEwsICZ0eXBlLCAoTFBCWVRFKWFyZ3NbMF0sICZzeik7CiAgICAgICAgfQogICAgICAgIHIgPSBzdGFydF9sb2NhbF9zZXJ2aWNlKGJ1ZiwgbnVtX2FyZ3MsIGFyZ3MpOwogICAgICAgIGlmIChyPT1FUlJPUl9TVUNDRVNTKQogICAgICAgICAgICBocmVzID0gU19PSzsKICAgICAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLDAsYXJnc1swXSk7CiAgICB9CiAgICBSZWdDbG9zZUtleShoa2V5KTsKICAgICAgICAKICAgIHJldHVybiBocmVzOwp9CgoKc3RhdGljIHZvaWQgZ2V0X2xvY2Fsc2VydmVyX3BpcGVfbmFtZShXQ0hBUiAqcGlwZWZuLCBSRUZDTFNJRCByY2xzaWQpCnsKICAgIHN0YXRpYyBjb25zdCBXQ0hBUiB3c3pQaXBlUmVmW10gPSB7J1xcJywnXFwnLCcuJywnXFwnLCdwJywnaScsJ3AnLCdlJywnXFwnLDB9OwogICAgc3RyY3B5VyhwaXBlZm4sIHdzelBpcGVSZWYpOwogICAgU3RyaW5nRnJvbUdVSUQyKHJjbHNpZCwgcGlwZWZuICsgc2l6ZW9mKHdzelBpcGVSZWYpL3NpemVvZih3c3pQaXBlUmVmWzBdKSAtIDEsIENIQVJTX0lOX0dVSUQpOwp9CgovKiBGSVhNRTogc2hvdWxkIGNhbGwgdG8gcnBjc3MgaW5zdGVhZCAqLwpIUkVTVUxUIFJQQ19HZXRMb2NhbENsYXNzT2JqZWN0KFJFRkNMU0lEIHJjbHNpZCwgUkVGSUlEIGlpZCwgTFBWT0lEICpwcHYpCnsKICAgIEhSRVNVTFQgICAgICAgIGhyZXM7CiAgICBIQU5ETEUgICAgICAgICBoUGlwZTsKICAgIFdDSEFSICAgICAgICAgIHBpcGVmblsxMDBdOwogICAgRFdPUkQgICAgICAgICAgcmVzLCBidWZmZXJsZW47CiAgICBjaGFyICAgICAgICAgICBtYXJzaGFsYnVmZmVyWzIwMF07CiAgICBJU3RyZWFtICAgICAgICpwU3RtOwogICAgTEFSR0VfSU5URUdFUiAgc2Vla3RvOwogICAgVUxBUkdFX0lOVEVHRVIgbmV3cG9zOwogICAgaW50ICAgICAgICAgICAgdHJpZXMgPSAwOwoKICAgIHN0YXRpYyBjb25zdCBpbnQgTUFYVFJJRVMgPSAzMDsgLyogMzAgc2Vjb25kcyAqLwoKICAgIFRSQUNFKCJyY2xzaWQ9JXMsIGlpZD0lc1xuIiwgZGVidWdzdHJfZ3VpZChyY2xzaWQpLCBkZWJ1Z3N0cl9ndWlkKGlpZCkpOwoKICAgIGdldF9sb2NhbHNlcnZlcl9waXBlX25hbWUocGlwZWZuLCByY2xzaWQpOwoKICAgIHdoaWxlICh0cmllcysrIDwgTUFYVFJJRVMpIHsKICAgICAgICBUUkFDRSgid2FpdGluZyBmb3IgJXNcbiIsIGRlYnVnc3RyX3cocGlwZWZuKSk7CiAgICAgIAogICAgICAgIFdhaXROYW1lZFBpcGVXKCBwaXBlZm4sIE5NUFdBSVRfV0FJVF9GT1JFVkVSICk7CiAgICAgICAgaFBpcGUgPSBDcmVhdGVGaWxlVyhwaXBlZm4sIEdFTkVSSUNfUkVBRCB8IEdFTkVSSUNfV1JJVEUsIDAsIE5VTEwsIE9QRU5fRVhJU1RJTkcsIDAsIDApOwogICAgICAgIGlmIChoUGlwZSA9PSBJTlZBTElEX0hBTkRMRV9WQUxVRSkgewogICAgICAgICAgICBpZiAodHJpZXMgPT0gMSkgewogICAgICAgICAgICAgICAgaWYgKCAoaHJlcyA9IGNyZWF0ZV9zZXJ2ZXIocmNsc2lkKSkgJiYKICAgICAgICAgICAgICAgICAgICAgKGhyZXMgPSBjcmVhdGVfbG9jYWxfc2VydmljZShyY2xzaWQpKSApCiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGhyZXM7CiAgICAgICAgICAgICAgICBTbGVlcCgxMDAwKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIFdBUk4oIkNvbm5lY3RpbmcgdG8gJXMsIG5vIHJlc3BvbnNlIHlldCwgcmV0cnlpbmc6IGxlIGlzICVseFxuIiwgZGVidWdzdHJfdyhwaXBlZm4pLCBHZXRMYXN0RXJyb3IoKSk7CiAgICAgICAgICAgICAgICBTbGVlcCgxMDAwKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBjb250aW51ZTsKICAgICAgICB9CiAgICAgICAgYnVmZmVybGVuID0gMDsKICAgICAgICBpZiAoIVJlYWRGaWxlKGhQaXBlLG1hcnNoYWxidWZmZXIsc2l6ZW9mKG1hcnNoYWxidWZmZXIpLCZidWZmZXJsZW4sTlVMTCkpIHsKICAgICAgICAgICAgRklYTUUoIkZhaWxlZCB0byByZWFkIG1hcnNoYWwgaWQgZnJvbSBjbGFzc2ZhY3Rvcnkgb2YgJXMuXG4iLGRlYnVnc3RyX2d1aWQocmNsc2lkKSk7CiAgICAgICAgICAgIFNsZWVwKDEwMDApOwogICAgICAgICAgICBjb250aW51ZTsKICAgICAgICB9CiAgICAgICAgVFJBQ0UoInJlYWQgbWFyc2hhbCBpZCBmcm9tIHBpcGVcbiIpOwogICAgICAgIENsb3NlSGFuZGxlKGhQaXBlKTsKICAgICAgICBicmVhazsKICAgIH0KICAgIAogICAgaWYgKHRyaWVzID49IE1BWFRSSUVTKQogICAgICAgIHJldHVybiBFX05PSU5URVJGQUNFOwogICAgCiAgICBocmVzID0gQ3JlYXRlU3RyZWFtT25IR2xvYmFsKDAsVFJVRSwmcFN0bSk7CiAgICBpZiAoaHJlcykgcmV0dXJuIGhyZXM7CiAgICBocmVzID0gSVN0cmVhbV9Xcml0ZShwU3RtLG1hcnNoYWxidWZmZXIsYnVmZmVybGVuLCZyZXMpOwogICAgaWYgKGhyZXMpIGdvdG8gb3V0OwogICAgc2Vla3RvLnUuTG93UGFydCA9IDA7c2Vla3RvLnUuSGlnaFBhcnQgPSAwOwogICAgaHJlcyA9IElTdHJlYW1fU2VlayhwU3RtLHNlZWt0byxTRUVLX1NFVCwmbmV3cG9zKTsKICAgIAogICAgVFJBQ0UoInVubWFyc2hhbGxpbmcgY2xhc3NmYWN0b3J5XG4iKTsKICAgIGhyZXMgPSBDb1VubWFyc2hhbEludGVyZmFjZShwU3RtLCZJSURfSUNsYXNzRmFjdG9yeSxwcHYpOwpvdXQ6CiAgICBJU3RyZWFtX1JlbGVhc2UocFN0bSk7CiAgICByZXR1cm4gaHJlczsKfQoKCnN0cnVjdCBsb2NhbF9zZXJ2ZXJfcGFyYW1zCnsKICAgIENMU0lEIGNsc2lkOwogICAgSVN0cmVhbSAqc3RyZWFtOwp9OwoKLyogRklYTUU6IHNob3VsZCBjYWxsIHRvIHJwY3NzIGluc3RlYWQgKi8Kc3RhdGljIERXT1JEIFdJTkFQSSBsb2NhbF9zZXJ2ZXJfdGhyZWFkKExQVk9JRCBwYXJhbSkKewogICAgc3RydWN0IGxvY2FsX3NlcnZlcl9wYXJhbXMgKiBsc3AgPSAoc3RydWN0IGxvY2FsX3NlcnZlcl9wYXJhbXMgKilwYXJhbTsKICAgIEhBTkRMRQkJaFBpcGU7CiAgICBXQ0hBUiAJCXBpcGVmblsxMDBdOwogICAgSFJFU1VMVAkJaHJlczsKICAgIElTdHJlYW0JCSpwU3RtID0gbHNwLT5zdHJlYW07CiAgICBTVEFUU1RHCQlzdHN0ZzsKICAgIHVuc2lnbmVkIGNoYXIJKmJ1ZmZlcjsKICAgIGludCAJCWJ1ZmxlbjsKICAgIExBUkdFX0lOVEVHRVIJc2Vla3RvOwogICAgVUxBUkdFX0lOVEVHRVIJbmV3cG9zOwogICAgVUxPTkcJCXJlczsKCiAgICBUUkFDRSgiU3RhcnRpbmcgdGhyZWFkZXIgZm9yICVzLlxuIixkZWJ1Z3N0cl9ndWlkKCZsc3AtPmNsc2lkKSk7CgogICAgZ2V0X2xvY2Fsc2VydmVyX3BpcGVfbmFtZShwaXBlZm4sICZsc3AtPmNsc2lkKTsKCiAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBsc3ApOwoKICAgIGhQaXBlID0gQ3JlYXRlTmFtZWRQaXBlVyggcGlwZWZuLCBQSVBFX0FDQ0VTU19EVVBMRVgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFBJUEVfVFlQRV9CWVRFfFBJUEVfV0FJVCwgUElQRV9VTkxJTUlURURfSU5TVEFOQ0VTLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICA0MDk2LCA0MDk2LCA1MDAgLyogMC41IHNlY29uZCB0aW1lb3V0ICovLCBOVUxMICk7CiAgICAKICAgIGlmIChoUGlwZSA9PSBJTlZBTElEX0hBTkRMRV9WQUxVRSkKICAgIHsKICAgICAgICBGSVhNRSgicGlwZSBjcmVhdGlvbiBmYWlsZWQgZm9yICVzLCBsZSBpcyAlbGRcbiIsIGRlYnVnc3RyX3cocGlwZWZuKSwgR2V0TGFzdEVycm9yKCkpOwogICAgICAgIHJldHVybiAxOwogICAgfQogICAgCiAgICB3aGlsZSAoMSkgewogICAgICAgIGlmICghQ29ubmVjdE5hbWVkUGlwZShoUGlwZSxOVUxMKSkgewogICAgICAgICAgICBFUlIoIkZhaWx1cmUgZHVyaW5nIENvbm5lY3ROYW1lZFBpcGUgJWxkLCBBQk9SVCFcbiIsR2V0TGFzdEVycm9yKCkpOwogICAgICAgICAgICBicmVhazsKICAgICAgICB9CgogICAgICAgIFRSQUNFKCJtYXJzaGFsbGluZyBJQ2xhc3NGYWN0b3J5IHRvIGNsaWVudFxuIik7CiAgICAgICAgCiAgICAgICAgaHJlcyA9IElTdHJlYW1fU3RhdChwU3RtLCZzdHN0ZywwKTsKICAgICAgICBpZiAoaHJlcykgcmV0dXJuIGhyZXM7CgogICAgICAgIGJ1ZmxlbiA9IHN0c3RnLmNiU2l6ZS51Lkxvd1BhcnQ7CiAgICAgICAgYnVmZmVyID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksMCxidWZsZW4pOwogICAgICAgIHNlZWt0by51Lkxvd1BhcnQgPSAwOwogICAgICAgIHNlZWt0by51LkhpZ2hQYXJ0ID0gMDsKICAgICAgICBocmVzID0gSVN0cmVhbV9TZWVrKHBTdG0sc2Vla3RvLFNFRUtfU0VULCZuZXdwb3MpOwogICAgICAgIGlmIChocmVzKSB7CiAgICAgICAgICAgIEZJWE1FKCJJU3RyZWFtX1NlZWsgZmFpbGVkLCAlbHhcbiIsaHJlcyk7CiAgICAgICAgICAgIHJldHVybiBocmVzOwogICAgICAgIH0KICAgICAgICAKICAgICAgICBocmVzID0gSVN0cmVhbV9SZWFkKHBTdG0sYnVmZmVyLGJ1ZmxlbiwmcmVzKTsKICAgICAgICBpZiAoaHJlcykgewogICAgICAgICAgICBGSVhNRSgiU3RyZWFtIFJlYWQgZmFpbGVkLCAlbHhcbiIsaHJlcyk7CiAgICAgICAgICAgIHJldHVybiBocmVzOwogICAgICAgIH0KICAgICAgICAKICAgICAgICBXcml0ZUZpbGUoaFBpcGUsYnVmZmVyLGJ1ZmxlbiwmcmVzLE5VTEwpOwogICAgICAgIEZsdXNoRmlsZUJ1ZmZlcnMoaFBpcGUpOwogICAgICAgIERpc2Nvbm5lY3ROYW1lZFBpcGUoaFBpcGUpOwoKICAgICAgICBUUkFDRSgiZG9uZSBtYXJzaGFsbGluZyBJQ2xhc3NGYWN0b3J5XG4iKTsKICAgIH0KICAgIENsb3NlSGFuZGxlKGhQaXBlKTsKICAgIElTdHJlYW1fUmVsZWFzZShwU3RtKTsKICAgIHJldHVybiAwOwp9Cgp2b2lkIFJQQ19TdGFydExvY2FsU2VydmVyKFJFRkNMU0lEIGNsc2lkLCBJU3RyZWFtICpzdHJlYW0pCnsKICAgIERXT1JEIHRpZDsKICAgIEhBTkRMRSB0aHJlYWQ7CiAgICBzdHJ1Y3QgbG9jYWxfc2VydmVyX3BhcmFtcyAqbHNwID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIDAsIHNpemVvZigqbHNwKSk7CgogICAgbHNwLT5jbHNpZCA9ICpjbHNpZDsKICAgIGxzcC0+c3RyZWFtID0gc3RyZWFtOwoKICAgIHRocmVhZCA9IENyZWF0ZVRocmVhZChOVUxMLCAwLCBsb2NhbF9zZXJ2ZXJfdGhyZWFkLCBsc3AsIDAsICZ0aWQpOwogICAgQ2xvc2VIYW5kbGUodGhyZWFkKTsKICAgIC8qIEZJWE1FOiBmYWlsdXJlIGhhbmRsaW5nICovCn0K