LyogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCiAqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAogKiB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCiAqIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCiAqICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCiAqIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICovCgovKgogKiBtb2RfYXV0aF9kaWdlc3Q6IE1ENSBkaWdlc3QgYXV0aGVudGljYXRpb24KICoKICogT3JpZ2luYWxseSBieSBBbGV4ZWkgS29zdXQgPGFrb3N1dEBudWV2YS5wdnQuazEyLmNhLnVzPgogKiBVcGRhdGVkIHRvIFJGQy0yNjE3IGJ5IFJvbmFsZCBUc2NoYWzkciA8cm9uYWxkQGlubm92YXRpb24uY2g+CiAqIGJhc2VkIG9uIG1vZF9hdXRoLCBieSBSb2IgTWNDb29sIGFuZCBSb2JlcnQgUy4gVGhhdQogKgogKiBUaGlzIG1vZHVsZSBhbiB1cGRhdGVkIHZlcnNpb24gb2YgbW9kdWxlcy9zdGFuZGFyZC9tb2RfZGlnZXN0LmMKICogSXQgaXMgc3RpbGwgZmFpcmx5IG5ldyBhbmQgcHJvYmxlbXMgbWF5IHR1cm4gdXAgLSBzdWJtaXQgcHJvYmxlbQogKiByZXBvcnRzIHRvIHRoZSBBcGFjaGUgYnVnLWRhdGFiYXNlLCBvciBzZW5kIHRoZW0gZGlyZWN0bHkgdG8gbWUKICogYXQgcm9uYWxkQGlubm92YXRpb24uY2guCiAqCiAqIE9wZW4gSXNzdWVzOgogKiAgIC0gcW9wPWF1dGgtaW50ICh3aGVuIHN0cmVhbXMgYW5kIHRyYWlsZXIgc3VwcG9ydCBhdmFpbGFibGUpCiAqICAgLSBub25jZS1mb3JtYXQgY29uZmlndXJhYmlsaXR5CiAqICAgLSBQcm94eS1BdXRob3JpemF0aW9uLUluZm8gaGVhZGVyIGlzIHNldCBieSB0aGlzIG1vZHVsZSwgYnV0IGlzCiAqICAgICBjdXJyZW50bHkgaWdub3JlZCBieSBtb2RfcHJveHkgKG5lZWRzIHBhdGNoIHRvIG1vZF9wcm94eSkKICogICAtIFRoZSBzb3VyY2Ugb2YgdGhlIHNlY3JldCBzaG91bGQgYmUgcnVuLXRpbWUgZGlyZWN0aXZlICh3aXRoIHNlcnZlcgogKiAgICAgc2NvcGU6IFJTUkNfQ09ORikKICogICAtIHNoYXJlZC1tZW0gbm90IGNvbXBsZXRlbHkgdGVzdGVkIHlldC4gU2VlbXMgdG8gd29yayBvayBmb3IgbWUsCiAqICAgICBidXQuLi4gKGRlZmluaXRlbHkgd29uJ3Qgd29yayBvbiBXaW5kb3plKQogKiAgIC0gU2hhcmluZyBhIHJlYWxtIGFtb25nIG11bHRpcGxlIHNlcnZlcnMgaGFzIGZvbGxvd2luZyBwcm9ibGVtczoKICogICAgIG8gU2VydmVyIG5hbWUgYW5kIHBvcnQgY2FuJ3QgYmUgaW5jbHVkZWQgaW4gbm9uY2UtaGFzaAogKiAgICAgICAod2UgbmVlZCB0d28gbm9uY2UgZm9ybWF0cywgd2hpY2ggbXVzdCBiZSBjb25maWd1cmVkIGV4cGxpY2l0bHkpCiAqICAgICBvIE5vbmNlLWNvdW50IGNoZWNrIGNhbid0IGJlIGZvciBlcXVhbCwgb3IgdGhlbiBub25jZS1jb3VudCBjaGVja2luZwogKiAgICAgICBtdXN0IGJlIGRpc2FibGVkLiBXaGF0IHdlIGNvdWxkIGRvIGlzIHRoZSBmb2xsb3dpbmc6CiAqICAgICAgIChleHBlY3RlZCA8IHJlY2VpdmVkKSA/IHNldCBleHBlY3RlZCA9IHJlY2VpdmVkIDogaXNzdWUgZXJyb3IKICogICAgICAgVGhlIG9ubHkgcHJvYmxlbSBpcyB0aGF0IGl0IGFsbG93cyByZXBsYXkgYXR0YWNrcyB3aGVuIHNvbWVib2R5CiAqICAgICAgIGNhcHR1cmVzIGEgcGFja2V0IHNlbnQgdG8gb25lIHNlcnZlciBhbmQgc2VuZHMgaXQgdG8gYW5vdGhlcgogKiAgICAgICBvbmUuIFNob3VsZCB3ZSBhZGQgIkF1dGhEaWdlc3ROY0NoZWNrIFN0cmljdCI/CiAqICAgLSBleHBpcmVkIG5vbmNlcyBnaXZlIGFtYXlhIGZpdHMuCiAqICAgLSBNRDUtc2VzcyBhbmQgYXV0aC1pbnQgYXJlIG5vdCB5ZXQgaW1wbGVtZW50ZWQuIEFuIGluY29tcGxldGUKICogICAgIGltcGxlbWVudGF0aW9uIGhhcyBiZWVuIHJlbW92ZWQgYW5kIGNhbiBiZSByZXRyaWV2ZWQgZnJvbSBzdm4gaGlzdG9yeS4KICovCgojaW5jbHVkZSAiYXByX3NoYTEuaCIKI2luY2x1ZGUgImFwcl9iYXNlNjQuaCIKI2luY2x1ZGUgImFwcl9saWIuaCIKI2luY2x1ZGUgImFwcl90aW1lLmgiCiNpbmNsdWRlICJhcHJfZXJybm8uaCIKI2luY2x1ZGUgImFwcl9nbG9iYWxfbXV0ZXguaCIKI2luY2x1ZGUgImFwcl9zdHJpbmdzLmgiCgojZGVmaW5lIEFQUl9XQU5UX1NUUkZVTkMKI2luY2x1ZGUgImFwcl93YW50LmgiCgojaW5jbHVkZSAiYXBfY29uZmlnLmgiCiNpbmNsdWRlICJodHRwZC5oIgojaW5jbHVkZSAiaHR0cF9jb25maWcuaCIKI2luY2x1ZGUgImh0dHBfY29yZS5oIgojaW5jbHVkZSAiaHR0cF9yZXF1ZXN0LmgiCiNpbmNsdWRlICJodHRwX2xvZy5oIgojaW5jbHVkZSAiaHR0cF9wcm90b2NvbC5oIgojaW5jbHVkZSAiYXByX3VyaS5oIgojaW5jbHVkZSAidXRpbF9tZDUuaCIKI2luY2x1ZGUgInV0aWxfbXV0ZXguaCIKI2luY2x1ZGUgImFwcl9zaG0uaCIKI2luY2x1ZGUgImFwcl9ybW0uaCIKI2luY2x1ZGUgImFwX3Byb3ZpZGVyLmgiCgojaW5jbHVkZSAibW9kX2F1dGguaCIKCiNpZiBBUFJfSEFWRV9VTklTVERfSAojaW5jbHVkZSA8dW5pc3RkLmg+CiNlbmRpZgoKLyogc3RydWN0IHRvIGhvbGQgdGhlIGNvbmZpZ3VyYXRpb24gaW5mbyAqLwoKdHlwZWRlZiBzdHJ1Y3QgZGlnZXN0X2NvbmZpZ19zdHJ1Y3QgewogICAgY29uc3QgY2hhciAgKmRpcl9uYW1lOwogICAgYXV0aG5fcHJvdmlkZXJfbGlzdCAqcHJvdmlkZXJzOwogICAgYXByX2FycmF5X2hlYWRlcl90ICpxb3BfbGlzdDsKICAgIGFwcl9zaGExX2N0eF90ICBub25jZV9jdHg7CiAgICBhcHJfdGltZV90ICAgIG5vbmNlX2xpZmV0aW1lOwogICAgaW50ICAgICAgICAgIGNoZWNrX25jOwogICAgY29uc3QgY2hhciAgKmFsZ29yaXRobTsKICAgIGNoYXIgICAgICAgICp1cmlfbGlzdDsKICAgIGNvbnN0IGNoYXIgICpoYTE7Cn0gZGlnZXN0X2NvbmZpZ19yZWM7CgoKI2RlZmluZSBERkxUX0FMR09SSVRITSAgIk1ENSIKCiNkZWZpbmUgREZMVF9OT05DRV9MSUZFIGFwcl90aW1lX2Zyb21fc2VjKDMwMCkKI2RlZmluZSBORVhUTk9OQ0VfREVMVEEgYXByX3RpbWVfZnJvbV9zZWMoMzApCgoKI2RlZmluZSBOT05DRV9USU1FX0xFTiAgKCgoc2l6ZW9mKGFwcl90aW1lX3QpKzIpLzMpKjQpCiNkZWZpbmUgTk9OQ0VfSEFTSF9MRU4gICgyKkFQUl9TSEExX0RJR0VTVFNJWkUpCiNkZWZpbmUgTk9OQ0VfTEVOICAgICAgIChpbnQgKShOT05DRV9USU1FX0xFTiArIE5PTkNFX0hBU0hfTEVOKQoKI2RlZmluZSBTRUNSRVRfTEVOICAgICAgICAgIDIwCiNkZWZpbmUgUkVUQUlORURfREFUQV9JRCAgICAibW9kX2F1dGhfZGlnZXN0IgoKCi8qIGNsaWVudCBsaXN0IGRlZmluaXRpb25zICovCgp0eXBlZGVmIHN0cnVjdCBoYXNoX2VudHJ5IHsKICAgIHVuc2lnbmVkIGxvbmcgICAgICBrZXk7ICAgICAgICAgICAgICAgICAgICAgLyogdGhlIGtleSBmb3IgdGhpcyBlbnRyeSAgICAqLwogICAgc3RydWN0IGhhc2hfZW50cnkgKm5leHQ7ICAgICAgICAgICAgICAgICAgICAvKiBuZXh0IGVudHJ5IGluIHRoZSBidWNrZXQgICovCiAgICB1bnNpZ25lZCBsb25nICAgICAgbm9uY2VfY291bnQ7ICAgICAgICAgICAgIC8qIGZvciBub25jZS1jb3VudCBjaGVja2luZyAgKi8KICAgIGNoYXIgICAgICAgICAgICAgICBsYXN0X25vbmNlW05PTkNFX0xFTisxXTsgLyogZm9yIG9uZS10aW1lIG5vbmNlJ3MgICAgICAqLwp9IGNsaWVudF9lbnRyeTsKCnN0YXRpYyBzdHJ1Y3QgaGFzaF90YWJsZSB7CiAgICBjbGllbnRfZW50cnkgICoqdGFibGU7CiAgICB1bnNpZ25lZCBsb25nICAgdGJsX2xlbjsKICAgIHVuc2lnbmVkIGxvbmcgICBudW1fZW50cmllczsKICAgIHVuc2lnbmVkIGxvbmcgICBudW1fY3JlYXRlZDsKICAgIHVuc2lnbmVkIGxvbmcgICBudW1fcmVtb3ZlZDsKICAgIHVuc2lnbmVkIGxvbmcgICBudW1fcmVuZXdlZDsKfSAqY2xpZW50X2xpc3Q7CgoKLyogc3RydWN0IHRvIGhvbGQgYSBwYXJzZWQgQXV0aG9yaXphdGlvbiBoZWFkZXIgKi8KCmVudW0gaGRyX3N0cyB7IE5PX0hFQURFUiwgTk9UX0RJR0VTVCwgSU5WQUxJRCwgVkFMSUQgfTsKCnR5cGVkZWYgc3RydWN0IGRpZ2VzdF9oZWFkZXJfc3RydWN0IHsKICAgIGNvbnN0IGNoYXIgICAgICAgICAgICpzY2hlbWU7CiAgICBjb25zdCBjaGFyICAgICAgICAgICAqcmVhbG07CiAgICBjb25zdCBjaGFyICAgICAgICAgICAqdXNlcm5hbWU7CiAgICAgICAgICBjaGFyICAgICAgICAgICAqbm9uY2U7CiAgICBjb25zdCBjaGFyICAgICAgICAgICAqdXJpOwogICAgY29uc3QgY2hhciAgICAgICAgICAgKm1ldGhvZDsKICAgIGNvbnN0IGNoYXIgICAgICAgICAgICpkaWdlc3Q7CiAgICBjb25zdCBjaGFyICAgICAgICAgICAqYWxnb3JpdGhtOwogICAgY29uc3QgY2hhciAgICAgICAgICAgKmNub25jZTsKICAgIGNvbnN0IGNoYXIgICAgICAgICAgICpvcGFxdWU7CiAgICB1bnNpZ25lZCBsb25nICAgICAgICAgb3BhcXVlX251bTsKICAgIGNvbnN0IGNoYXIgICAgICAgICAgICptZXNzYWdlX3FvcDsKICAgIGNvbnN0IGNoYXIgICAgICAgICAgICpub25jZV9jb3VudDsKICAgIC8qIHRoZSBmb2xsb3dpbmcgZmllbGRzIGFyZSBub3QgKGRpcmVjdGx5KSBmcm9tIHRoZSBoZWFkZXIgKi8KICAgIGNvbnN0IGNoYXIgICAgICAgICAgICpyYXdfcmVxdWVzdF91cmk7CiAgICBhcHJfdXJpX3QgICAgICAgICAgICAqcHNkX3JlcXVlc3RfdXJpOwogICAgYXByX3RpbWVfdCAgICAgICAgICAgIG5vbmNlX3RpbWU7CiAgICBlbnVtIGhkcl9zdHMgICAgICAgICAgYXV0aF9oZHJfc3RzOwogICAgaW50ICAgICAgICAgICAgICAgICAgIG5lZWRlZF9hdXRoOwogICAgY2xpZW50X2VudHJ5ICAgICAgICAgKmNsaWVudDsKfSBkaWdlc3RfaGVhZGVyX3JlYzsKCgovKiAobW9zdGx5KSBub25jZSBzdHVmZiAqLwoKdHlwZWRlZiB1bmlvbiB0aW1lX3VuaW9uIHsKICAgIGFwcl90aW1lX3QgICAgdGltZTsKICAgIHVuc2lnbmVkIGNoYXIgYXJyW3NpemVvZihhcHJfdGltZV90KV07Cn0gdGltZV9yZWM7CgpzdGF0aWMgdW5zaWduZWQgY2hhciAqc2VjcmV0OwoKLyogY2xpZW50LWxpc3QsIG9wYXF1ZSwgYW5kIG9uZS10aW1lLW5vbmNlIHN0dWZmICovCgpzdGF0aWMgYXByX3NobV90ICAgICAgKmNsaWVudF9zaG0gPSAgTlVMTDsKc3RhdGljIGFwcl9ybW1fdCAgICAgICpjbGllbnRfcm1tID0gTlVMTDsKc3RhdGljIHVuc2lnbmVkIGxvbmcgICpvcGFxdWVfY250cjsKc3RhdGljIGFwcl90aW1lX3QgICAgICpvdG5fY291bnRlcjsgICAgIC8qIG9uZS10aW1lLW5vbmNlIGNvdW50ZXIgKi8Kc3RhdGljIGFwcl9nbG9iYWxfbXV0ZXhfdCAqY2xpZW50X2xvY2sgPSBOVUxMOwpzdGF0aWMgYXByX2dsb2JhbF9tdXRleF90ICpvcGFxdWVfbG9jayA9IE5VTEw7CnN0YXRpYyBjb25zdCBjaGFyICAgICAqY2xpZW50X211dGV4X3R5cGUgPSAiYXV0aGRpZ2VzdC1jbGllbnQiOwpzdGF0aWMgY29uc3QgY2hhciAgICAgKm9wYXF1ZV9tdXRleF90eXBlID0gImF1dGhkaWdlc3Qtb3BhcXVlIjsKc3RhdGljIGNvbnN0IGNoYXIgICAgICpjbGllbnRfc2htX2ZpbGVuYW1lOwoKI2RlZmluZSBERUZfU0hNRU1fU0laRSAgMTAwMEwgICAgICAgICAgIC8qIH4gMTIgZW50cmllcyAqLwojZGVmaW5lIERFRl9OVU1fQlVDS0VUUyAxNUwKI2RlZmluZSBIQVNIX0RFUFRIICAgICAgNQoKc3RhdGljIGFwcl9zaXplX3Qgc2htZW1fc2l6ZSAgPSBERUZfU0hNRU1fU0laRTsKc3RhdGljIHVuc2lnbmVkIGxvbmcgbnVtX2J1Y2tldHMgPSBERUZfTlVNX0JVQ0tFVFM7CgoKbW9kdWxlIEFQX01PRFVMRV9ERUNMQVJFX0RBVEEgYXV0aF9kaWdlc3RfbW9kdWxlOwoKLyoKICogaW5pdGlhbGl6YXRpb24gY29kZQogKi8KCnN0YXRpYyBhcHJfc3RhdHVzX3QgY2xlYW51cF90YWJsZXModm9pZCAqbm90X3VzZWQpCnsKICAgIGFwX2xvZ19lcnJvcihBUExPR19NQVJLLCBBUExPR19JTkZPLCAwLCBOVUxMLCBBUExPR05PKDAxNzU2KQogICAgICAgICAgICAgICAgICAiY2xlYW5pbmcgdXAgc2hhcmVkIG1lbW9yeSIpOwoKICAgIGlmIChjbGllbnRfcm1tKSB7CiAgICAgICAgYXByX3JtbV9kZXN0cm95KGNsaWVudF9ybW0pOwogICAgICAgIGNsaWVudF9ybW0gPSBOVUxMOwogICAgfQoKICAgIGlmIChjbGllbnRfc2htKSB7CiAgICAgICAgYXByX3NobV9kZXN0cm95KGNsaWVudF9zaG0pOwogICAgICAgIGNsaWVudF9zaG0gPSBOVUxMOwogICAgfQoKICAgIGlmIChjbGllbnRfbG9jaykgewogICAgICAgIGFwcl9nbG9iYWxfbXV0ZXhfZGVzdHJveShjbGllbnRfbG9jayk7CiAgICAgICAgY2xpZW50X2xvY2sgPSBOVUxMOwogICAgfQoKICAgIGlmIChvcGFxdWVfbG9jaykgewogICAgICAgIGFwcl9nbG9iYWxfbXV0ZXhfZGVzdHJveShvcGFxdWVfbG9jayk7CiAgICAgICAgb3BhcXVlX2xvY2sgPSBOVUxMOwogICAgfQoKICAgIGNsaWVudF9saXN0ID0gTlVMTDsKCiAgICByZXR1cm4gQVBSX1NVQ0NFU1M7Cn0KCnN0YXRpYyB2b2lkIGxvZ19lcnJvcl9hbmRfY2xlYW51cChjaGFyICptc2csIGFwcl9zdGF0dXNfdCBzdHMsIHNlcnZlcl9yZWMgKnMpCnsKICAgIGFwX2xvZ19lcnJvcihBUExPR19NQVJLLCBBUExPR19FUlIsIHN0cywgcywgQVBMT0dOTygwMTc2MCkKICAgICAgICAgICAgICAgICAiJXMgLSBhbGwgbm9uY2UtY291bnQgY2hlY2tpbmcgYW5kIG9uZS10aW1lIG5vbmNlcyAiCiAgICAgICAgICAgICAgICAgImRpc2FibGVkIiwgbXNnKTsKCiAgICBjbGVhbnVwX3RhYmxlcyhOVUxMKTsKfQoKI2lmIEFQUl9IQVNfU0hBUkVEX01FTU9SWQoKc3RhdGljIGludCBpbml0aWFsaXplX3RhYmxlcyhzZXJ2ZXJfcmVjICpzLCBhcHJfcG9vbF90ICpjdHgpCnsKICAgIHVuc2lnbmVkIGxvbmcgaWR4OwogICAgYXByX3N0YXR1c190ICAgc3RzOwoKICAgIC8qIHNldCB1cCBjbGllbnQgbGlzdCAqLwoKICAgIC8qIENyZWF0ZSB0aGUgc2hhcmVkIG1lbW9yeSBzZWdtZW50ICovCgogICAgLyoKICAgICAqIENyZWF0ZSBhIHVuaXF1ZSBmaWxlbmFtZSB1c2luZyBvdXIgcGlkLiBUaGlzIGluZm9ybWF0aW9uIGlzCiAgICAgKiBzdGFzaGVkIGluIHRoZSBnbG9iYWwgdmFyaWFibGUgc28gdGhlIGNoaWxkcmVuIGluaGVyaXQgaXQuCiAgICAgKi8KICAgIGNsaWVudF9zaG1fZmlsZW5hbWUgPSBhcF9ydW50aW1lX2Rpcl9yZWxhdGl2ZShjdHgsICJhdXRoZGlnZXN0X3NobSIpOwogICAgY2xpZW50X3NobV9maWxlbmFtZSA9IGFwX2FwcGVuZF9waWQoY3R4LCBjbGllbnRfc2htX2ZpbGVuYW1lLCAiLiIpOwoKICAgIC8qIFVzZSBhbm9ueW1vdXMgc2htIGJ5IGRlZmF1bHQsIGZhbGwgYmFjayBvbiBuYW1lLWJhc2VkLiAqLwogICAgc3RzID0gYXByX3NobV9jcmVhdGUoJmNsaWVudF9zaG0sIHNobWVtX3NpemUsIE5VTEwsIGN0eCk7CiAgICBpZiAoQVBSX1NUQVRVU19JU19FTk9USU1QTChzdHMpKSB7CiAgICAgICAgLyogRm9yIGEgbmFtZS1iYXNlZCBzZWdtZW50LCByZW1vdmUgaXQgZmlyc3QgaW4gY2FzZSBvZiBhCiAgICAgICAgICogcHJldmlvdXMgdW5jbGVhbiBzaHV0ZG93bi4gKi8KICAgICAgICBhcHJfc2htX3JlbW92ZShjbGllbnRfc2htX2ZpbGVuYW1lLCBjdHgpOwoKICAgICAgICAvKiBOb3cgY3JlYXRlIHRoYXQgc2VnbWVudCAqLwogICAgICAgIHN0cyA9IGFwcl9zaG1fY3JlYXRlKCZjbGllbnRfc2htLCBzaG1lbV9zaXplLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xpZW50X3NobV9maWxlbmFtZSwgY3R4KTsKICAgIH0KCiAgICBpZiAoQVBSX1NVQ0NFU1MgIT0gc3RzKSB7CiAgICAgICAgYXBfbG9nX2Vycm9yKEFQTE9HX01BUkssIEFQTE9HX0VSUiwgc3RzLCBzLCBBUExPR05PKDAxNzYyKQogICAgICAgICAgICAgICAgICAgICAiRmFpbGVkIHRvIGNyZWF0ZSBzaGFyZWQgbWVtb3J5IHNlZ21lbnQgb24gZmlsZSAlcyIsCiAgICAgICAgICAgICAgICAgICAgIGNsaWVudF9zaG1fZmlsZW5hbWUpOwogICAgICAgIGxvZ19lcnJvcl9hbmRfY2xlYW51cCgiZmFpbGVkIHRvIGluaXRpYWxpemUgc2htIiwgc3RzLCBzKTsKICAgICAgICByZXR1cm4gSFRUUF9JTlRFUk5BTF9TRVJWRVJfRVJST1I7CiAgICB9CgogICAgc3RzID0gYXByX3JtbV9pbml0KCZjbGllbnRfcm1tLAogICAgICAgICAgICAgICAgICAgICAgIE5VTEwsIC8qIG5vIGxvY2ssIHdlJ2xsIGRvIHRoZSBsb2NraW5nIG91cnNlbHZlcyAqLwogICAgICAgICAgICAgICAgICAgICAgIGFwcl9zaG1fYmFzZWFkZHJfZ2V0KGNsaWVudF9zaG0pLAogICAgICAgICAgICAgICAgICAgICAgIHNobWVtX3NpemUsIGN0eCk7CiAgICBpZiAoc3RzICE9IEFQUl9TVUNDRVNTKSB7CiAgICAgICAgbG9nX2Vycm9yX2FuZF9jbGVhbnVwKCJmYWlsZWQgdG8gaW5pdGlhbGl6ZSBybW0iLCBzdHMsIHMpOwogICAgICAgIHJldHVybiAhT0s7CiAgICB9CgogICAgY2xpZW50X2xpc3QgPSBhcHJfcm1tX2FkZHJfZ2V0KGNsaWVudF9ybW0sIGFwcl9ybW1fbWFsbG9jKGNsaWVudF9ybW0sIHNpemVvZigqY2xpZW50X2xpc3QpICsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNpemVvZihjbGllbnRfZW50cnkqKSpudW1fYnVja2V0cykpOwogICAgaWYgKCFjbGllbnRfbGlzdCkgewogICAgICAgIGxvZ19lcnJvcl9hbmRfY2xlYW51cCgiZmFpbGVkIHRvIGFsbG9jYXRlIHNoYXJlZCBtZW1vcnkiLCAtMSwgcyk7CiAgICAgICAgcmV0dXJuICFPSzsKICAgIH0KICAgIGNsaWVudF9saXN0LT50YWJsZSA9IChjbGllbnRfZW50cnkqKikgKGNsaWVudF9saXN0ICsgMSk7CiAgICBmb3IgKGlkeCA9IDA7IGlkeCA8IG51bV9idWNrZXRzOyBpZHgrKykgewogICAgICAgIGNsaWVudF9saXN0LT50YWJsZVtpZHhdID0gTlVMTDsKICAgIH0KICAgIGNsaWVudF9saXN0LT50YmxfbGVuICAgICA9IG51bV9idWNrZXRzOwogICAgY2xpZW50X2xpc3QtPm51bV9lbnRyaWVzID0gMDsKCiAgICBzdHMgPSBhcF9nbG9iYWxfbXV0ZXhfY3JlYXRlKCZjbGllbnRfbG9jaywgTlVMTCwgY2xpZW50X211dGV4X3R5cGUsIE5VTEwsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHMsIGN0eCwgMCk7CiAgICBpZiAoc3RzICE9IEFQUl9TVUNDRVNTKSB7CiAgICAgICAgbG9nX2Vycm9yX2FuZF9jbGVhbnVwKCJmYWlsZWQgdG8gY3JlYXRlIGxvY2sgKGNsaWVudF9sb2NrKSIsIHN0cywgcyk7CiAgICAgICAgcmV0dXJuICFPSzsKICAgIH0KCgogICAgLyogc2V0dXAgb3BhcXVlICovCgogICAgb3BhcXVlX2NudHIgPSBhcHJfcm1tX2FkZHJfZ2V0KGNsaWVudF9ybW0sIGFwcl9ybW1fbWFsbG9jKGNsaWVudF9ybW0sIHNpemVvZigqb3BhcXVlX2NudHIpKSk7CiAgICBpZiAob3BhcXVlX2NudHIgPT0gTlVMTCkgewogICAgICAgIGxvZ19lcnJvcl9hbmRfY2xlYW51cCgiZmFpbGVkIHRvIGFsbG9jYXRlIHNoYXJlZCBtZW1vcnkiLCAtMSwgcyk7CiAgICAgICAgcmV0dXJuICFPSzsKICAgIH0KICAgICpvcGFxdWVfY250ciA9IDFVTDsKCiAgICBzdHMgPSBhcF9nbG9iYWxfbXV0ZXhfY3JlYXRlKCZvcGFxdWVfbG9jaywgTlVMTCwgb3BhcXVlX211dGV4X3R5cGUsIE5VTEwsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHMsIGN0eCwgMCk7CiAgICBpZiAoc3RzICE9IEFQUl9TVUNDRVNTKSB7CiAgICAgICAgbG9nX2Vycm9yX2FuZF9jbGVhbnVwKCJmYWlsZWQgdG8gY3JlYXRlIGxvY2sgKG9wYXF1ZV9sb2NrKSIsIHN0cywgcyk7CiAgICAgICAgcmV0dXJuICFPSzsKICAgIH0KCgogICAgLyogc2V0dXAgb25lLXRpbWUtbm9uY2UgY291bnRlciAqLwoKICAgIG90bl9jb3VudGVyID0gYXByX3JtbV9hZGRyX2dldChjbGllbnRfcm1tLCBhcHJfcm1tX21hbGxvYyhjbGllbnRfcm1tLCBzaXplb2YoKm90bl9jb3VudGVyKSkpOwogICAgaWYgKG90bl9jb3VudGVyID09IE5VTEwpIHsKICAgICAgICBsb2dfZXJyb3JfYW5kX2NsZWFudXAoImZhaWxlZCB0byBhbGxvY2F0ZSBzaGFyZWQgbWVtb3J5IiwgLTEsIHMpOwogICAgICAgIHJldHVybiAhT0s7CiAgICB9CiAgICAqb3RuX2NvdW50ZXIgPSAwOwogICAgLyogbm8gbG9jayBoZXJlICovCgoKICAgIC8qIHN1Y2Nlc3MgKi8KICAgIHJldHVybiBPSzsKfQoKI2VuZGlmIC8qIEFQUl9IQVNfU0hBUkVEX01FTU9SWSAqLwoKc3RhdGljIGludCBwcmVfaW5pdChhcHJfcG9vbF90ICpwY29uZiwgYXByX3Bvb2xfdCAqcGxvZywgYXByX3Bvb2xfdCAqcHRlbXApCnsKICAgIGFwcl9zdGF0dXNfdCBydjsKICAgIHZvaWQgKnJldGFpbmVkOwoKICAgIHJ2ID0gYXBfbXV0ZXhfcmVnaXN0ZXIocGNvbmYsIGNsaWVudF9tdXRleF90eXBlLCBOVUxMLCBBUFJfTE9DS19ERUZBVUxULCAwKTsKICAgIGlmIChydiAhPSBBUFJfU1VDQ0VTUykKICAgICAgICByZXR1cm4gIU9LOwogICAgcnYgPSBhcF9tdXRleF9yZWdpc3RlcihwY29uZiwgb3BhcXVlX211dGV4X3R5cGUsIE5VTEwsIEFQUl9MT0NLX0RFRkFVTFQsIDApOwogICAgaWYgKHJ2ICE9IEFQUl9TVUNDRVNTKQogICAgICAgIHJldHVybiAhT0s7CgogICAgcmV0YWluZWQgPSBhcF9yZXRhaW5lZF9kYXRhX2dldChSRVRBSU5FRF9EQVRBX0lEKTsKICAgIGlmIChyZXRhaW5lZCA9PSBOVUxMKSB7CiAgICAgICAgcmV0YWluZWQgPSBhcF9yZXRhaW5lZF9kYXRhX2NyZWF0ZShSRVRBSU5FRF9EQVRBX0lELCBTRUNSRVRfTEVOKTsKICAgICAgICBhcF9sb2dfZXJyb3IoQVBMT0dfTUFSSywgQVBMT0dfREVCVUcsIDAsIE5VTEwsIEFQTE9HTk8oMDE3NTcpCiAgICAgICAgICAgICAgICAgICAgICJnZW5lcmF0aW5nIHNlY3JldCBmb3IgZGlnZXN0IGF1dGhlbnRpY2F0aW9uIik7CiNpZiBBUFJfSEFTX1JBTkRPTQogICAgICAgIHJ2ID0gYXByX2dlbmVyYXRlX3JhbmRvbV9ieXRlcyhyZXRhaW5lZCwgU0VDUkVUX0xFTik7CiNlbHNlCiNlcnJvciBBUFIgcmFuZG9tIG51bWJlciBzdXBwb3J0IGlzIG1pc3NpbmcKI2VuZGlmCiAgICAgICAgaWYgKHJ2ICE9IEFQUl9TVUNDRVNTKSB7CiAgICAgICAgICAgIGFwX2xvZ19lcnJvcihBUExPR19NQVJLLCBBUExPR19DUklULCBydiwgTlVMTCwgQVBMT0dOTygwMTc1OCkKICAgICAgICAgICAgICAgICAgICAgICAgICJlcnJvciBnZW5lcmF0aW5nIHNlY3JldCIpOwogICAgICAgICAgICByZXR1cm4gIU9LOwogICAgICAgIH0KICAgIH0KICAgIHNlY3JldCA9IHJldGFpbmVkOwogICAgcmV0dXJuIE9LOwp9CgpzdGF0aWMgaW50IGluaXRpYWxpemVfbW9kdWxlKGFwcl9wb29sX3QgKnAsIGFwcl9wb29sX3QgKnBsb2csCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXByX3Bvb2xfdCAqcHRlbXAsIHNlcnZlcl9yZWMgKnMpCnsKICAgIC8qIGluaXRpYWxpemVfbW9kdWxlKCkgd2lsbCBiZSBjYWxsZWQgdHdpY2UsIGFuZCBpZiBpdCdzIGEgRFNPCiAgICAgKiB0aGVuIGFsbCBzdGF0aWMgZGF0YSBmcm9tIHRoZSBmaXJzdCBjYWxsIHdpbGwgYmUgbG9zdC4gT25seQogICAgICogc2V0IHVwIG91ciBzdGF0aWMgZGF0YSBvbiB0aGUgc2Vjb25kIGNhbGwuICovCiAgICBpZiAoYXBfc3RhdGVfcXVlcnkoQVBfU1FfTUFJTl9TVEFURSkgPT0gQVBfU1FfTVNfQ1JFQVRFX1BSRV9DT05GSUcpCiAgICAgICAgcmV0dXJuIE9LOwoKI2lmIEFQUl9IQVNfU0hBUkVEX01FTU9SWQogICAgLyogTm90ZTogdGhpcyBzdHVmZiBpcyBjdXJyZW50bHkgZml4ZWQgZm9yIHRoZSBsaWZldGltZSBvZiB0aGUgc2VydmVyLAogICAgICogaS5lLiBldmVuIGFjcm9zcyByZXN0YXJ0cy4gVGhpcyBtZWFucyB0aGF0IEEpIGFueSBzaG1lbS1zaXplCiAgICAgKiBjb25maWd1cmF0aW9uIGNoYW5nZXMgYXJlIGlnbm9yZWQsIGFuZCBCKSBjZXJ0YWluIG9wdGltaXphdGlvbnMsCiAgICAgKiBzdWNoIGFzIG9ubHkgYWxsb2NhdGluZyB0aGUgc21hbGxlc3QgbmVjZXNzYXJ5IGVudHJ5IGZvciBlYWNoCiAgICAgKiBjbGllbnQsIGNhbid0IGJlIGRvbmUuIEhvd2V2ZXIsIHRoZSBhbHRlcm5hdGl2ZSBpcyBhIG5pZ2h0bWFyZToKICAgICAqIHdlIGNhbid0IGNhbGwgYXByX3NobV9kZXN0cm95IG9uIGEgZ3JhY2VmdWwgcmVzdGFydCBiZWNhdXNlIHRoZXJlCiAgICAgKiB3aWxsIGJlIGNoaWxkcmVuIHVzaW5nIHRoZSB0YWJsZXMsIGFuZCB3ZSBhbHNvIGRvbid0IGtub3cgd2hlbiB0aGUKICAgICAqIGxhc3QgY2hpbGQgZGllcy4gVGhlcmVmb3JlIHdlIGNhbiBuZXZlciBjbGVhbiB1cCB0aGUgb2xkIHN0dWZmLAogICAgICogY3JlYXRpbmcgYSBjcmVlcGluZyBtZW1vcnkgbGVhay4KICAgICAqLwogICAgaWYgKGluaXRpYWxpemVfdGFibGVzKHMsIHApICE9IE9LKSB7CiAgICAgICAgcmV0dXJuICFPSzsKICAgIH0KICAgIC8qIENhbGwgY2xlYW51cF90YWJsZXMgb24gZXhpdCBvciByZXN0YXJ0ICovCiAgICBhcHJfcG9vbF9jbGVhbnVwX3JlZ2lzdGVyKHAsIE5VTEwsIGNsZWFudXBfdGFibGVzLCBhcHJfcG9vbF9jbGVhbnVwX251bGwpOwojZW5kaWYgIC8qIEFQUl9IQVNfU0hBUkVEX01FTU9SWSAqLwogICAgcmV0dXJuIE9LOwp9CgpzdGF0aWMgdm9pZCBpbml0aWFsaXplX2NoaWxkKGFwcl9wb29sX3QgKnAsIHNlcnZlcl9yZWMgKnMpCnsKICAgIGFwcl9zdGF0dXNfdCBzdHM7CgogICAgaWYgKCFjbGllbnRfc2htKSB7CiAgICAgICAgcmV0dXJuOwogICAgfQoKICAgIC8qIEdldCBhY2Nlc3MgdG8gcm1tIGluIGNoaWxkICovCiAgICBzdHMgPSBhcHJfcm1tX2F0dGFjaCgmY2xpZW50X3JtbSwKICAgICAgICAgICAgICAgICAgICAgICAgIE5VTEwsCiAgICAgICAgICAgICAgICAgICAgICAgICBhcHJfc2htX2Jhc2VhZGRyX2dldChjbGllbnRfc2htKSwKICAgICAgICAgICAgICAgICAgICAgICAgIHApOwogICAgaWYgKHN0cyAhPSBBUFJfU1VDQ0VTUykgewogICAgICAgIGxvZ19lcnJvcl9hbmRfY2xlYW51cCgiZmFpbGVkIHRvIGF0dGFjaCB0byBybW0iLCBzdHMsIHMpOwogICAgICAgIHJldHVybjsKICAgIH0KCiAgICBzdHMgPSBhcHJfZ2xvYmFsX211dGV4X2NoaWxkX2luaXQoJmNsaWVudF9sb2NrLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFwcl9nbG9iYWxfbXV0ZXhfbG9ja2ZpbGUoY2xpZW50X2xvY2spLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHApOwogICAgaWYgKHN0cyAhPSBBUFJfU1VDQ0VTUykgewogICAgICAgIGxvZ19lcnJvcl9hbmRfY2xlYW51cCgiZmFpbGVkIHRvIGNyZWF0ZSBsb2NrIChjbGllbnRfbG9jaykiLCBzdHMsIHMpOwogICAgICAgIHJldHVybjsKICAgIH0KICAgIHN0cyA9IGFwcl9nbG9iYWxfbXV0ZXhfY2hpbGRfaW5pdCgmb3BhcXVlX2xvY2ssCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXByX2dsb2JhbF9tdXRleF9sb2NrZmlsZShvcGFxdWVfbG9jayksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcCk7CiAgICBpZiAoc3RzICE9IEFQUl9TVUNDRVNTKSB7CiAgICAgICAgbG9nX2Vycm9yX2FuZF9jbGVhbnVwKCJmYWlsZWQgdG8gY3JlYXRlIGxvY2sgKG9wYXF1ZV9sb2NrKSIsIHN0cywgcyk7CiAgICAgICAgcmV0dXJuOwogICAgfQp9CgovKgogKiBjb25maWd1cmF0aW9uIGNvZGUKICovCgpzdGF0aWMgdm9pZCAqY3JlYXRlX2RpZ2VzdF9kaXJfY29uZmlnKGFwcl9wb29sX3QgKnAsIGNoYXIgKmRpcikKewogICAgZGlnZXN0X2NvbmZpZ19yZWMgKmNvbmY7CgogICAgaWYgKGRpciA9PSBOVUxMKSB7CiAgICAgICAgcmV0dXJuIE5VTEw7CiAgICB9CgogICAgY29uZiA9IChkaWdlc3RfY29uZmlnX3JlYyAqKSBhcHJfcGNhbGxvYyhwLCBzaXplb2YoZGlnZXN0X2NvbmZpZ19yZWMpKTsKICAgIGlmIChjb25mKSB7CiAgICAgICAgY29uZi0+cW9wX2xpc3QgICAgICAgPSBhcHJfYXJyYXlfbWFrZShwLCAyLCBzaXplb2YoY2hhciAqKSk7CiAgICAgICAgY29uZi0+bm9uY2VfbGlmZXRpbWUgPSBERkxUX05PTkNFX0xJRkU7CiAgICAgICAgY29uZi0+ZGlyX25hbWUgICAgICAgPSBhcHJfcHN0cmR1cChwLCBkaXIpOwogICAgICAgIGNvbmYtPmFsZ29yaXRobSAgICAgID0gREZMVF9BTEdPUklUSE07CiAgICB9CgogICAgcmV0dXJuIGNvbmY7Cn0KCgovKgogKiBUaGUgcmVhbG0gaXMgbm8gbG9uZ2VyIHByZWNvbXB1dGVkIGJlY2F1c2UgaXQgbWF5IGJlIGFuIGV4cHJlc3Npb24sIHdoaWNoCiAqIG1ha2VzIHRoaXMgaG9va2luZyBvZiBBdXRoTmFtZSBxdWl0ZSB3ZWlyZC4KICovCnN0YXRpYyBjb25zdCBjaGFyICpzZXRfcmVhbG0oY21kX3Bhcm1zICpjbWQsIHZvaWQgKmNvbmZpZywgY29uc3QgY2hhciAqcmVhbG0pCnsKICAgIGRpZ2VzdF9jb25maWdfcmVjICpjb25mID0gKGRpZ2VzdF9jb25maWdfcmVjICopIGNvbmZpZzsKI2lmZGVmIEFQX0RFQlVHCiAgICBpbnQgaTsKCiAgICAvKiBjaGVjayB0aGF0IHdlIGdvdCByYW5kb20gbnVtYmVycyAqLwogICAgZm9yIChpID0gMDsgaSA8IFNFQ1JFVF9MRU47IGkrKykgewogICAgICAgIGlmIChzZWNyZXRbaV0gIT0gMCkKICAgICAgICAgICAgYnJlYWs7CiAgICB9CiAgICBhcF9hc3NlcnQoaSA8IFNFQ1JFVF9MRU4pOwojZW5kaWYKCiAgICAvKiB3ZSBwcmVjb21wdXRlIHRoZSBwYXJ0IG9mIHRoZSBub25jZSBoYXNoIHRoYXQgaXMgY29uc3RhbnQgKHdlbGwsCiAgICAgKiB0aGUgaG9zdDpwb3J0IHdvdWxkIGJlIHRvbywgYnV0IHRoYXQgdmFyaWVzIGZvciAuaHRhY2Nlc3MgZmlsZXMKICAgICAqIGFuZCBkaXJlY3RpdmVzIG91dHNpZGUgYSB2aXJ0dWFsIGhvc3Qgc2VjdGlvbikKICAgICAqLwogICAgYXByX3NoYTFfaW5pdCgmY29uZi0+bm9uY2VfY3R4KTsKICAgIGFwcl9zaGExX3VwZGF0ZV9iaW5hcnkoJmNvbmYtPm5vbmNlX2N0eCwgc2VjcmV0LCBTRUNSRVRfTEVOKTsKCgogICAgcmV0dXJuIERFQ0xJTkVfQ01EOwp9CgpzdGF0aWMgY29uc3QgY2hhciAqYWRkX2F1dGhuX3Byb3ZpZGVyKGNtZF9wYXJtcyAqY21kLCB2b2lkICpjb25maWcsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgY2hhciAqYXJnKQp7CiAgICBkaWdlc3RfY29uZmlnX3JlYyAqY29uZiA9IChkaWdlc3RfY29uZmlnX3JlYyopY29uZmlnOwogICAgYXV0aG5fcHJvdmlkZXJfbGlzdCAqbmV3cDsKCiAgICBuZXdwID0gYXByX3BjYWxsb2MoY21kLT5wb29sLCBzaXplb2YoYXV0aG5fcHJvdmlkZXJfbGlzdCkpOwogICAgbmV3cC0+cHJvdmlkZXJfbmFtZSA9IGFyZzsKCiAgICAvKiBsb29rdXAgYW5kIGNhY2hlIHRoZSBhY3R1YWwgcHJvdmlkZXIgbm93ICovCiAgICBuZXdwLT5wcm92aWRlciA9IGFwX2xvb2t1cF9wcm92aWRlcihBVVRITl9QUk9WSURFUl9HUk9VUCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ld3AtPnByb3ZpZGVyX25hbWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBVVRITl9QUk9WSURFUl9WRVJTSU9OKTsKCiAgICBpZiAobmV3cC0+cHJvdmlkZXIgPT0gTlVMTCkgewogICAgICAgLyogYnkgdGhlIHRpbWUgdGhleSB1c2UgaXQsIHRoZSBwcm92aWRlciBzaG91bGQgYmUgbG9hZGVkIGFuZAogICAgICAgICAgIHJlZ2lzdGVyZWQgd2l0aCB1cy4gKi8KICAgICAgICByZXR1cm4gYXByX3BzcHJpbnRmKGNtZC0+cG9vbCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICJVbmtub3duIEF1dGhuIHByb3ZpZGVyOiAlcyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXdwLT5wcm92aWRlcl9uYW1lKTsKICAgIH0KCiAgICBpZiAoIW5ld3AtPnByb3ZpZGVyLT5nZXRfcmVhbG1faGFzaCkgewogICAgICAgIC8qIGlmIGl0IGRvZXNuJ3QgcHJvdmlkZSB0aGUgYXBwcm9wcmlhdGUgZnVuY3Rpb24sIHJlamVjdCBpdCAqLwogICAgICAgIHJldHVybiBhcHJfcHNwcmludGYoY21kLT5wb29sLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIlRoZSAnJXMnIEF1dGhuIHByb3ZpZGVyIGRvZXNuJ3Qgc3VwcG9ydCAiCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAiRGlnZXN0IEF1dGhlbnRpY2F0aW9uIiwgbmV3cC0+cHJvdmlkZXJfbmFtZSk7CiAgICB9CgogICAgLyogQWRkIGl0IHRvIHRoZSBsaXN0IG5vdy4gKi8KICAgIGlmICghY29uZi0+cHJvdmlkZXJzKSB7CiAgICAgICAgY29uZi0+cHJvdmlkZXJzID0gbmV3cDsKICAgIH0KICAgIGVsc2UgewogICAgICAgIGF1dGhuX3Byb3ZpZGVyX2xpc3QgKmxhc3QgPSBjb25mLT5wcm92aWRlcnM7CgogICAgICAgIHdoaWxlIChsYXN0LT5uZXh0KSB7CiAgICAgICAgICAgIGxhc3QgPSBsYXN0LT5uZXh0OwogICAgICAgIH0KICAgICAgICBsYXN0LT5uZXh0ID0gbmV3cDsKICAgIH0KCiAgICByZXR1cm4gTlVMTDsKfQoKc3RhdGljIGNvbnN0IGNoYXIgKnNldF9xb3AoY21kX3Bhcm1zICpjbWQsIHZvaWQgKmNvbmZpZywgY29uc3QgY2hhciAqb3ApCnsKICAgIGRpZ2VzdF9jb25maWdfcmVjICpjb25mID0gKGRpZ2VzdF9jb25maWdfcmVjICopIGNvbmZpZzsKCiAgICBpZiAoIXN0cmNhc2VjbXAob3AsICJub25lIikpIHsKICAgICAgICBhcHJfYXJyYXlfY2xlYXIoY29uZi0+cW9wX2xpc3QpOwogICAgICAgICooY29uc3QgY2hhciAqKilhcHJfYXJyYXlfcHVzaChjb25mLT5xb3BfbGlzdCkgPSAibm9uZSI7CiAgICAgICAgcmV0dXJuIE5VTEw7CiAgICB9CgogICAgaWYgKCFzdHJjYXNlY21wKG9wLCAiYXV0aC1pbnQiKSkgewogICAgICAgIHJldHVybiAiQXV0aERpZ2VzdFFvcCBhdXRoLWludCBpcyBub3QgaW1wbGVtZW50ZWQiOwogICAgfQogICAgZWxzZSBpZiAoYXBfY3N0cl9jYXNlY21wKG9wLCAiYXV0aCIpKSB7CiAgICAgICAgcmV0dXJuIGFwcl9wc3RyY2F0KGNtZC0+cG9vbCwgIlVucmVjb2duaXplZCBxb3A6ICIsIG9wLCBOVUxMKTsKICAgIH0KCiAgICAqKGNvbnN0IGNoYXIgKiopYXByX2FycmF5X3B1c2goY29uZi0+cW9wX2xpc3QpID0gb3A7CgogICAgcmV0dXJuIE5VTEw7Cn0KCnN0YXRpYyBjb25zdCBjaGFyICpzZXRfbm9uY2VfbGlmZXRpbWUoY21kX3Bhcm1zICpjbWQsIHZvaWQgKmNvbmZpZywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBjaGFyICp0KQp7CiAgICBjaGFyICplbmRwdHI7CiAgICBsb25nICBsaWZldGltZTsKCiAgICBsaWZldGltZSA9IHN0cnRvbCh0LCAmZW5kcHRyLCAxMCk7CiAgICBpZiAoZW5kcHRyIDwgKHQrc3RybGVuKHQpKSAmJiAhYXByX2lzc3BhY2UoKmVuZHB0cikpIHsKICAgICAgICByZXR1cm4gYXByX3BzdHJjYXQoY21kLT5wb29sLAogICAgICAgICAgICAgICAgICAgICAgICAgICAiSW52YWxpZCB0aW1lIGluIEF1dGhEaWdlc3ROb25jZUxpZmV0aW1lOiAiLAogICAgICAgICAgICAgICAgICAgICAgICAgICB0LCBOVUxMKTsKICAgIH0KCiAgICAoKGRpZ2VzdF9jb25maWdfcmVjICopIGNvbmZpZyktPm5vbmNlX2xpZmV0aW1lID0gYXByX3RpbWVfZnJvbV9zZWMobGlmZXRpbWUpOwogICAgcmV0dXJuIE5VTEw7Cn0KCnN0YXRpYyBjb25zdCBjaGFyICpzZXRfbm9uY2VfZm9ybWF0KGNtZF9wYXJtcyAqY21kLCB2b2lkICpjb25maWcsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGNoYXIgKmZtdCkKewogICAgcmV0dXJuICJBdXRoRGlnZXN0Tm9uY2VGb3JtYXQgaXMgbm90IGltcGxlbWVudGVkIjsKfQoKc3RhdGljIGNvbnN0IGNoYXIgKnNldF9uY19jaGVjayhjbWRfcGFybXMgKmNtZCwgdm9pZCAqY29uZmlnLCBpbnQgZmxhZykKewojaWYgIUFQUl9IQVNfU0hBUkVEX01FTU9SWQogICAgaWYgKGZsYWcpIHsKICAgICAgICByZXR1cm4gIkF1dGhEaWdlc3ROY0NoZWNrOiBFUlJPUjogbm9uY2UtY291bnQgY2hlY2tpbmcgIgogICAgICAgICAgICAgICAgICAgICAiaXMgbm90IHN1cHBvcnRlZCBvbiBwbGF0Zm9ybXMgd2l0aG91dCBzaGFyZWQtbWVtb3J5ICIKICAgICAgICAgICAgICAgICAgICAgInN1cHBvcnQiOwogICAgfQojZW5kaWYKCiAgICAoKGRpZ2VzdF9jb25maWdfcmVjICopIGNvbmZpZyktPmNoZWNrX25jID0gZmxhZzsKICAgIHJldHVybiBOVUxMOwp9CgpzdGF0aWMgY29uc3QgY2hhciAqc2V0X2FsZ29yaXRobShjbWRfcGFybXMgKmNtZCwgdm9pZCAqY29uZmlnLCBjb25zdCBjaGFyICphbGcpCnsKICAgIGlmICghc3RyY2FzZWNtcChhbGcsICJNRDUtc2VzcyIpKSB7CiAgICAgICAgcmV0dXJuICJBdXRoRGlnZXN0QWxnb3JpdGhtOiBFUlJPUjogYWxnb3JpdGhtIGBNRDUtc2VzcycgIgogICAgICAgICAgICAgICAgImlzIG5vdCBpbXBsZW1lbnRlZCI7CiAgICB9CiAgICBlbHNlIGlmIChhcF9jc3RyX2Nhc2VjbXAoYWxnLCAiTUQ1IikpIHsKICAgICAgICByZXR1cm4gYXByX3BzdHJjYXQoY21kLT5wb29sLCAiSW52YWxpZCBhbGdvcml0aG0gaW4gQXV0aERpZ2VzdEFsZ29yaXRobTogIiwgYWxnLCBOVUxMKTsKICAgIH0KCiAgICAoKGRpZ2VzdF9jb25maWdfcmVjICopIGNvbmZpZyktPmFsZ29yaXRobSA9IGFsZzsKICAgIHJldHVybiBOVUxMOwp9CgpzdGF0aWMgY29uc3QgY2hhciAqc2V0X3VyaV9saXN0KGNtZF9wYXJtcyAqY21kLCB2b2lkICpjb25maWcsIGNvbnN0IGNoYXIgKnVyaSkKewogICAgZGlnZXN0X2NvbmZpZ19yZWMgKmMgPSAoZGlnZXN0X2NvbmZpZ19yZWMgKikgY29uZmlnOwogICAgaWYgKGMtPnVyaV9saXN0KSB7CiAgICAgICAgYy0+dXJpX2xpc3Rbc3RybGVuKGMtPnVyaV9saXN0KS0xXSA9ICdcMCc7CiAgICAgICAgYy0+dXJpX2xpc3QgPSBhcHJfcHN0cmNhdChjbWQtPnBvb2wsIGMtPnVyaV9saXN0LCAiICIsIHVyaSwgIlwiIiwgTlVMTCk7CiAgICB9CiAgICBlbHNlIHsKICAgICAgICBjLT51cmlfbGlzdCA9IGFwcl9wc3RyY2F0KGNtZC0+cG9vbCwgIiwgZG9tYWluPVwiIiwgdXJpLCAiXCIiLCBOVUxMKTsKICAgIH0KICAgIHJldHVybiBOVUxMOwp9CgpzdGF0aWMgY29uc3QgY2hhciAqc2V0X3NobWVtX3NpemUoY21kX3Bhcm1zICpjbWQsIHZvaWQgKmNvbmZpZywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGNoYXIgKnNpemVfc3RyKQp7CiAgICBjaGFyICplbmRwdHI7CiAgICBsb25nICBzaXplLCBtaW47CgogICAgc2l6ZSA9IHN0cnRvbChzaXplX3N0ciwgJmVuZHB0ciwgMTApOwogICAgd2hpbGUgKGFwcl9pc3NwYWNlKCplbmRwdHIpKSBlbmRwdHIrKzsKICAgIGlmICgqZW5kcHRyID09ICdcMCcgfHwgKmVuZHB0ciA9PSAnYicgfHwgKmVuZHB0ciA9PSAnQicpIHsKICAgICAgICA7CiAgICB9CiAgICBlbHNlIGlmICgqZW5kcHRyID09ICdrJyB8fCAqZW5kcHRyID09ICdLJykgewogICAgICAgIHNpemUgKj0gMTAyNDsKICAgIH0KICAgIGVsc2UgaWYgKCplbmRwdHIgPT0gJ20nIHx8ICplbmRwdHIgPT0gJ00nKSB7CiAgICAgICAgc2l6ZSAqPSAxMDQ4NTc2OwogICAgfQogICAgZWxzZSB7CiAgICAgICAgcmV0dXJuIGFwcl9wc3RyY2F0KGNtZC0+cG9vbCwgIkludmFsaWQgc2l6ZSBpbiBBdXRoRGlnZXN0U2htZW1TaXplOiAiLAogICAgICAgICAgICAgICAgICAgICAgICAgIHNpemVfc3RyLCBOVUxMKTsKICAgIH0KCiAgICBtaW4gPSBzaXplb2YoKmNsaWVudF9saXN0KSArIHNpemVvZihjbGllbnRfZW50cnkqKSArIHNpemVvZihjbGllbnRfZW50cnkpOwogICAgaWYgKHNpemUgPCBtaW4pIHsKICAgICAgICByZXR1cm4gYXByX3BzcHJpbnRmKGNtZC0+cG9vbCwgInNpemUgaW4gQXV0aERpZ2VzdFNobWVtU2l6ZSB0b28gc21hbGw6ICIKICAgICAgICAgICAgICAgICAgICAgICAgICAgIiVsZCA8ICVsZCIsIHNpemUsIG1pbik7CiAgICB9CgogICAgc2htZW1fc2l6ZSAgPSBzaXplOwogICAgbnVtX2J1Y2tldHMgPSAoc2l6ZSAtIHNpemVvZigqY2xpZW50X2xpc3QpKSAvCiAgICAgICAgICAgICAgICAgIChzaXplb2YoY2xpZW50X2VudHJ5KikgKyBIQVNIX0RFUFRIICogc2l6ZW9mKGNsaWVudF9lbnRyeSkpOwogICAgaWYgKG51bV9idWNrZXRzID09IDApIHsKICAgICAgICBudW1fYnVja2V0cyA9IDE7CiAgICB9CiAgICBhcF9sb2dfZXJyb3IoQVBMT0dfTUFSSywgQVBMT0dfREVCVUcsIDAsIGNtZC0+c2VydmVyLCBBUExPR05PKDAxNzYzKQogICAgICAgICAgICAgICAgICJTZXQgc2htZW0tc2l6ZTogJSIgQVBSX1NJWkVfVF9GTVQgIiwgbnVtLWJ1Y2tldHM6ICVsZCIsCiAgICAgICAgICAgICAgICAgc2htZW1fc2l6ZSwgbnVtX2J1Y2tldHMpOwoKICAgIHJldHVybiBOVUxMOwp9CgpzdGF0aWMgY29uc3QgY29tbWFuZF9yZWMgZGlnZXN0X2NtZHNbXSA9CnsKICAgIEFQX0lOSVRfVEFLRTEoIkF1dGhOYW1lIiwgc2V0X3JlYWxtLCBOVUxMLCBPUl9BVVRIQ0ZHLAogICAgICJUaGUgYXV0aGVudGljYXRpb24gcmVhbG0gKGUuZy4gXCJNZW1iZXJzIE9ubHlcIikiKSwKICAgIEFQX0lOSVRfSVRFUkFURSgiQXV0aERpZ2VzdFByb3ZpZGVyIiwgYWRkX2F1dGhuX3Byb3ZpZGVyLCBOVUxMLCBPUl9BVVRIQ0ZHLAogICAgICAgICAgICAgICAgICAgICAic3BlY2lmeSB0aGUgYXV0aCBwcm92aWRlcnMgZm9yIGEgZGlyZWN0b3J5IG9yIGxvY2F0aW9uIiksCiAgICBBUF9JTklUX0lURVJBVEUoIkF1dGhEaWdlc3RRb3AiLCBzZXRfcW9wLCBOVUxMLCBPUl9BVVRIQ0ZHLAogICAgICJBIGxpc3Qgb2YgcXVhbGl0eS1vZi1wcm90ZWN0aW9uIG9wdGlvbnMiKSwKICAgIEFQX0lOSVRfVEFLRTEoIkF1dGhEaWdlc3ROb25jZUxpZmV0aW1lIiwgc2V0X25vbmNlX2xpZmV0aW1lLCBOVUxMLCBPUl9BVVRIQ0ZHLAogICAgICJNYXhpbXVtIGxpZmV0aW1lIG9mIHRoZSBzZXJ2ZXIgbm9uY2UgKHNlY29uZHMpIiksCiAgICBBUF9JTklUX1RBS0UxKCJBdXRoRGlnZXN0Tm9uY2VGb3JtYXQiLCBzZXRfbm9uY2VfZm9ybWF0LCBOVUxMLCBPUl9BVVRIQ0ZHLAogICAgICJUaGUgZm9ybWF0IHRvIHVzZSB3aGVuIGdlbmVyYXRpbmcgdGhlIHNlcnZlciBub25jZSIpLAogICAgQVBfSU5JVF9GTEFHKCJBdXRoRGlnZXN0TmNDaGVjayIsIHNldF9uY19jaGVjaywgTlVMTCwgT1JfQVVUSENGRywKICAgICAiV2hldGhlciBvciBub3QgdG8gY2hlY2sgdGhlIG5vbmNlLWNvdW50IHNlbnQgYnkgdGhlIGNsaWVudCIpLAogICAgQVBfSU5JVF9UQUtFMSgiQXV0aERpZ2VzdEFsZ29yaXRobSIsIHNldF9hbGdvcml0aG0sIE5VTEwsIE9SX0FVVEhDRkcsCiAgICAgIlRoZSBhbGdvcml0aG0gdXNlZCBmb3IgdGhlIGhhc2ggY2FsY3VsYXRpb24iKSwKICAgIEFQX0lOSVRfSVRFUkFURSgiQXV0aERpZ2VzdERvbWFpbiIsIHNldF91cmlfbGlzdCwgTlVMTCwgT1JfQVVUSENGRywKICAgICAiQSBsaXN0IG9mIFVSSSdzIHdoaWNoIGJlbG9uZyB0byB0aGUgc2FtZSBwcm90ZWN0aW9uIHNwYWNlIGFzIHRoZSBjdXJyZW50IFVSSSIpLAogICAgQVBfSU5JVF9UQUtFMSgiQXV0aERpZ2VzdFNobWVtU2l6ZSIsIHNldF9zaG1lbV9zaXplLCBOVUxMLCBSU1JDX0NPTkYsCiAgICAgIlRoZSBhbW91bnQgb2Ygc2hhcmVkIG1lbW9yeSB0byBhbGxvY2F0ZSBmb3Iga2VlcGluZyB0cmFjayBvZiBjbGllbnRzIiksCiAgICB7TlVMTH0KfTsKCgovKgogKiBjbGllbnQgbGlzdCBjb2RlCiAqCiAqIEVhY2ggY2xpZW50IGlzIGFzc2lnbmVkIGEgbnVtYmVyLCB3aGljaCBpcyB0cmFuc2ZlcnJlZCBpbiB0aGUgb3BhcXVlCiAqIGZpZWxkIG9mIHRoZSBXV1ctQXV0aGVudGljYXRlIGFuZCBBdXRob3JpemF0aW9uIGhlYWRlcnMuIFRoZSBudW1iZXIKICogaXMganVzdCBhIHNpbXBsZSBjb3VudGVyIHdoaWNoIGlzIGluY3JlbWVudGVkIGZvciBlYWNoIG5ldyBjbGllbnQuCiAqIENsaWVudHMgY2FuJ3QgZm9yZ2UgdGhpcyBudW1iZXIgYmVjYXVzZSBpdCBpcyBoYXNoZWQgdXAgaW50byB0aGUKICogc2VydmVyIG5vbmNlLCBhbmQgdGhhdCBpcyBjaGVja2VkLgogKgogKiBUaGUgY2xpZW50cyBhcmUga2VwdCBpbiBhIHNpbXBsZSBoYXNoIHRhYmxlLCB3aGljaCBjb25zaXN0cyBvZiBhbgogKiBhcnJheSBvZiBjbGllbnRfZW50cnkncywgZWFjaCB3aXRoIGEgbGlua2VkIGxpc3Qgb2YgZW50cmllcyBoYW5naW5nCiAqIG9mZiBpdC4gVGhlIGNsaWVudCdzIG51bWJlciBtb2R1bG8gdGhlIHNpemUgb2YgdGhlIGFycmF5IGdpdmVzIHRoZQogKiBidWNrZXQgbnVtYmVyLgogKgogKiBUaGUgY2xpZW50cyBhcmUgZ2FyYmFnZSBjb2xsZWN0ZWQgd2hlbmV2ZXIgYSBuZXcgY2xpZW50IGlzIGFsbG9jYXRlZAogKiBidXQgdGhlcmUgaXMgbm90IGVub3VnaCBzcGFjZSBsZWZ0IGluIHRoZSBzaGFyZWQgbWVtb3J5IHNlZ21lbnQuIEEKICogc2ltcGxlIHNlbWktTFJVIGlzIHVzZWQgZm9yIHRoaXM6IHdoZW5ldmVyIGEgY2xpZW50IGVudHJ5IGlzIGFjY2Vzc2VkCiAqIGl0IGlzIG1vdmVkIHRvIHRoZSBiZWdpbm5pbmcgb2YgdGhlIGxpbmtlZCBsaXN0IGluIGl0cyBidWNrZXQgKHRoaXMKICogYWxzbyBtYWtlcyBmb3IgZmFzdGVyIGxvb2t1cHMgZm9yIGN1cnJlbnQgY2xpZW50cykuIFRoZSBnYXJiYWdlCiAqIGNvbGxlY3RlciB0aGVuIGp1c3QgcmVtb3ZlcyB0aGUgb2xkZXN0IGVudHJ5IChpLmUuIHRoZSBvbmUgYXQgdGhlCiAqIGVuZCBvZiB0aGUgbGlzdCkgaW4gZWFjaCBidWNrZXQuCiAqCiAqIFRoZSBtYWluIGFkdmFudGFnZXMgb2YgdGhlIGFib3ZlIHNjaGVtZSBhcmUgdGhhdCBpdCdzIGVhc3kgdG8gaW1wbGVtZW50CiAqIGFuZCBpdCBrZWVwcyB0aGUgaGFzaCB0YWJsZSBldmVubHkgYmFsYW5jZWQgKGkuZS4gc2FtZSBudW1iZXIgb2YgZW50cmllcwogKiBpbiBlYWNoIGJ1Y2tldCkuIFRoZSBtYWpvciBkaXNhZHZhbnRhZ2UgaXMgdGhhdCB5b3UgbWF5IGJlIHRocm93aW5nCiAqIGVudHJpZXMgb3V0IHdoaWNoIGFyZSBpbiBhY3RpdmUgdXNlLiBUaGlzIGlzIG5vdCB0cmFnaWMsIGFzIHRoZXNlCiAqIGNsaWVudHMgd2lsbCBqdXN0IGJlIHNlbnQgYSBuZXcgY2xpZW50IGlkIChvcGFxdWUgZmllbGQpIGFuZCBub25jZQogKiB3aXRoIGEgc3RhbGU9dHJ1ZSAoaS5lLiBpdCB3aWxsIGp1c3QgbG9vayBsaWtlIHRoZSBub25jZSBleHBpcmVkLAogKiB0aGVyZWJ5IGZvcmNpbmcgYW4gZXh0cmEgcm91bmQgdHJpcCkuIElmIHRoZSBzaGFyZWQgbWVtb3J5IHNlZ21lbnQKICogaGFzIGVub3VnaCBoZWFkcm9vbSBvdmVyIHRoZSBjdXJyZW50IGNsaWVudCBzZXQgc2l6ZSB0aGVuIHRoaXMgc2hvdWxkCiAqIG5vdCBvY2N1ciB0b28gb2Z0ZW4uCiAqCiAqIFRvIGhlbHAgdHVuZSB0aGUgc2l6ZSBvZiB0aGUgc2hhcmVkIG1lbW9yeSBzZWdtZW50IChhbmQgc2VlIGlmIHRoZQogKiBhYm92ZSBhbGdvcml0aG0gaXMgcmVhbGx5IHN1ZmZpY2llbnQpIGEgc2V0IG9mIGNvdW50ZXJzIGlzIGtlcHQKICogaW5kaWNhdGluZyB0aGUgbnVtYmVyIG9mIGNsaWVudHMgaGVsZCwgdGhlIG51bWJlciBvZiBnYXJiYWdlIGNvbGxlY3RlZAogKiBjbGllbnRzLCBhbmQgdGhlIG51bWJlciBvZiBlcnJvbmVvdXNseSBwdXJnZWQgY2xpZW50cy4gVGhlc2UgYXJlIHByaW50ZWQKICogb3V0IGF0IGVhY2ggZ2FyYmFnZSBjb2xsZWN0aW9uIHJ1bi4gTm90ZSB0aGF0IGFjY2VzcyB0byB0aGUgY291bnRlcnMgaXMKICogbm90IHN5bmNocm9uaXplZCBiZWNhdXNlIHRoZXkgYXJlIGp1c3QgaW5kaWNhdGVycywgYW5kIHdoZXRoZXIgdGhleSBhcmUKICogb2ZmIGJ5IGEgZmV3IGRvZXNuJ3QgbWF0dGVyOyBhbmQgZm9yIHRoZSBzYW1lIHJlYXNvbiBubyBhdHRlbXB0IGlzIG1hZGUKICogdG8gZ3VhcmFudGVlIHRoZSBudW1fcmVuZXdlZCBpcyBjb3JyZWN0IGluIHRoZSBmYWNlIG9mIGNsaWVudHMgc3Bvb2ZpbmcKICogdGhlIG9wYXF1ZSBmaWVsZC4KICovCgovKgogKiBHZXQgdGhlIGNsaWVudCBnaXZlbiBpdHMgY2xpZW50IG51bWJlciAodGhlIGtleSkuIFJldHVybnMgdGhlIGVudHJ5LAogKiBvciBOVUxMIGlmIGl0J3Mgbm90IGZvdW5kLgogKgogKiBBY2Nlc3MgdG8gdGhlIGxpc3QgaXRzZWxmIGlzIHN5bmNocm9uaXplZCB2aWEgbG9ja3MuIEhvd2V2ZXIsIGFjY2VzcwogKiB0byB0aGUgZW50cnkgcmV0dXJuZWQgYnkgZ2V0X2NsaWVudCgpIGlzIE5PVCBzeW5jaHJvbml6ZWQuIFRoaXMgbWVhbnMKICogdGhhdCB0aGVyZSBhcmUgcG90ZW50aWFsbHkgcHJvYmxlbXMgaWYgYSBjbGllbnQgdXNlcyBtdWx0aXBsZSwKICogc2ltdWx0YW5lb3VzIGNvbm5lY3Rpb25zIHRvIGFjY2VzcyB1cmwncyB3aXRoaW4gdGhlIHNhbWUgcHJvdGVjdGlvbgogKiBzcGFjZS4gSG93ZXZlciwgdGhlc2UgcHJvYmxlbXMgYXJlIG5vdCBuZXc6IHdoZW4gdXNpbmcgbXVsdGlwbGUKICogY29ubmVjdGlvbnMgeW91IGhhdmUgbm8gZ3VhcmFudGVlIG9mIHRoZSBvcmRlciB0aGUgcmVxdWVzdHMgYXJlCiAqIHByb2Nlc3NlZCBhbnl3YXksIHNvIHlvdSBoYXZlIHByb2JsZW1zIHdpdGggdGhlIG5vbmNlLWNvdW50IGFuZAogKiBvbmUtdGltZSBub25jZXMgYW55d2F5LgogKi8Kc3RhdGljIGNsaWVudF9lbnRyeSAqZ2V0X2NsaWVudCh1bnNpZ25lZCBsb25nIGtleSwgY29uc3QgcmVxdWVzdF9yZWMgKnIpCnsKICAgIGludCBidWNrZXQ7CiAgICBjbGllbnRfZW50cnkgKmVudHJ5LCAqcHJldiA9IE5VTEw7CgoKICAgIGlmICgha2V5IHx8ICFjbGllbnRfc2htKSAgcmV0dXJuIE5VTEw7CgogICAgYnVja2V0ID0ga2V5ICUgY2xpZW50X2xpc3QtPnRibF9sZW47CiAgICBlbnRyeSAgPSBjbGllbnRfbGlzdC0+dGFibGVbYnVja2V0XTsKCiAgICBhcHJfZ2xvYmFsX211dGV4X2xvY2soY2xpZW50X2xvY2spOwoKICAgIHdoaWxlIChlbnRyeSAmJiBrZXkgIT0gZW50cnktPmtleSkgewogICAgICAgIHByZXYgID0gZW50cnk7CiAgICAgICAgZW50cnkgPSBlbnRyeS0+bmV4dDsKICAgIH0KCiAgICBpZiAoZW50cnkgJiYgcHJldikgeyAgICAgICAgICAgICAgICAvKiBtb3ZlIGVudHJ5IHRvIGZyb250IG9mIGxpc3QgKi8KICAgICAgICBwcmV2LT5uZXh0ICA9IGVudHJ5LT5uZXh0OwogICAgICAgIGVudHJ5LT5uZXh0ID0gY2xpZW50X2xpc3QtPnRhYmxlW2J1Y2tldF07CiAgICAgICAgY2xpZW50X2xpc3QtPnRhYmxlW2J1Y2tldF0gPSBlbnRyeTsKICAgIH0KCiAgICBhcHJfZ2xvYmFsX211dGV4X3VubG9jayhjbGllbnRfbG9jayk7CgogICAgaWYgKGVudHJ5KSB7CiAgICAgICAgYXBfbG9nX3JlcnJvcihBUExPR19NQVJLLCBBUExPR19ERUJVRywgMCwgciwgQVBMT0dOTygwMTc2NCkKICAgICAgICAgICAgICAgICAgICAgICJnZXRfY2xpZW50KCk6IGNsaWVudCAlbHUgZm91bmQiLCBrZXkpOwogICAgfQogICAgZWxzZSB7CiAgICAgICAgYXBfbG9nX3JlcnJvcihBUExPR19NQVJLLCBBUExPR19ERUJVRywgMCwgciwgQVBMT0dOTygwMTc2NSkKICAgICAgICAgICAgICAgICAgICAgICJnZXRfY2xpZW50KCk6IGNsaWVudCAlbHUgbm90IGZvdW5kIiwga2V5KTsKICAgIH0KCiAgICByZXR1cm4gZW50cnk7Cn0KCgovKiBBIHNpbXBsZSBnYXJiYWdlLWNvbGxlY3RlciB0byByZW1vdmUgdW51c2VkIGNsaWVudHMuIEl0IHJlbW92ZXMgdGhlCiAqIGxhc3QgZW50cnkgaW4gZWFjaCBidWNrZXQgYW5kIHVwZGF0ZXMgdGhlIGNvdW50ZXJzLiBSZXR1cm5zIHRoZQogKiBudW1iZXIgb2YgcmVtb3ZlZCBlbnRyaWVzLgogKi8Kc3RhdGljIGxvbmcgZ2Modm9pZCkKewogICAgY2xpZW50X2VudHJ5ICplbnRyeSwgKnByZXY7CiAgICB1bnNpZ25lZCBsb25nIG51bV9yZW1vdmVkID0gMCwgaWR4OwoKICAgIC8qIGdhcmJhZ2UgY29sbGVjdCBhbGwgbGFzdCBlbnRyaWVzICovCgogICAgZm9yIChpZHggPSAwOyBpZHggPCBjbGllbnRfbGlzdC0+dGJsX2xlbjsgaWR4KyspIHsKICAgICAgICBlbnRyeSA9IGNsaWVudF9saXN0LT50YWJsZVtpZHhdOwogICAgICAgIHByZXYgID0gTlVMTDsKICAgICAgICB3aGlsZSAoZW50cnktPm5leHQpIHsgICAvKiBmaW5kIGxhc3QgZW50cnkgKi8KICAgICAgICAgICAgcHJldiAgPSBlbnRyeTsKICAgICAgICAgICAgZW50cnkgPSBlbnRyeS0+bmV4dDsKICAgICAgICB9CiAgICAgICAgaWYgKHByZXYpIHsKICAgICAgICAgICAgcHJldi0+bmV4dCA9IE5VTEw7ICAgLyogY3V0IGxpc3QgKi8KICAgICAgICB9CiAgICAgICAgZWxzZSB7CiAgICAgICAgICAgIGNsaWVudF9saXN0LT50YWJsZVtpZHhdID0gTlVMTDsKICAgICAgICB9CiAgICAgICAgaWYgKGVudHJ5KSB7ICAgICAgICAgICAgICAgICAgICAvKiByZW1vdmUgZW50cnkgKi8KICAgICAgICAgICAgYXByX3JtbV9mcmVlKGNsaWVudF9ybW0sIGFwcl9ybW1fb2Zmc2V0X2dldChjbGllbnRfcm1tLCBlbnRyeSkpOwogICAgICAgICAgICBudW1fcmVtb3ZlZCsrOwogICAgICAgIH0KICAgIH0KCiAgICAvKiB1cGRhdGUgY291bnRlcnMgYW5kIGxvZyAqLwoKICAgIGNsaWVudF9saXN0LT5udW1fZW50cmllcyAtPSBudW1fcmVtb3ZlZDsKICAgIGNsaWVudF9saXN0LT5udW1fcmVtb3ZlZCArPSBudW1fcmVtb3ZlZDsKCiAgICByZXR1cm4gbnVtX3JlbW92ZWQ7Cn0KCgovKgogKiBBZGQgYSBuZXcgY2xpZW50IHRvIHRoZSBsaXN0LiBSZXR1cm5zIHRoZSBlbnRyeSBpZiBzdWNjZXNzZnVsLCBOVUxMCiAqIG90aGVyd2lzZS4gVGhpcyB0cmlnZ2VycyB0aGUgZ2FyYmFnZSBjb2xsZWN0aW9uIGlmIG1lbW9yeSBpcyBsb3cuCiAqLwpzdGF0aWMgY2xpZW50X2VudHJ5ICphZGRfY2xpZW50KHVuc2lnbmVkIGxvbmcga2V5LCBjbGllbnRfZW50cnkgKmluZm8sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VydmVyX3JlYyAqcykKewogICAgaW50IGJ1Y2tldDsKICAgIGNsaWVudF9lbnRyeSAqZW50cnk7CgoKICAgIGlmICgha2V5IHx8ICFjbGllbnRfc2htKSB7CiAgICAgICAgcmV0dXJuIE5VTEw7CiAgICB9CgogICAgYnVja2V0ID0ga2V5ICUgY2xpZW50X2xpc3QtPnRibF9sZW47CgogICAgYXByX2dsb2JhbF9tdXRleF9sb2NrKGNsaWVudF9sb2NrKTsKCiAgICAvKiB0cnkgdG8gYWxsb2NhdGUgYSBuZXcgZW50cnkgKi8KCiAgICBlbnRyeSA9IGFwcl9ybW1fYWRkcl9nZXQoY2xpZW50X3JtbSwgYXByX3JtbV9tYWxsb2MoY2xpZW50X3JtbSwgc2l6ZW9mKGNsaWVudF9lbnRyeSkpKTsKICAgIGlmICghZW50cnkpIHsKICAgICAgICBsb25nIG51bV9yZW1vdmVkID0gZ2MoKTsKICAgICAgICBhcF9sb2dfZXJyb3IoQVBMT0dfTUFSSywgQVBMT0dfSU5GTywgMCwgcywgQVBMT0dOTygwMTc2NikKICAgICAgICAgICAgICAgICAgICAgImdjJ2QgJWxkIGNsaWVudCBlbnRyaWVzLiBUb3RhbCBuZXcgY2xpZW50czogIgogICAgICAgICAgICAgICAgICAgICAiJWxkOyBUb3RhbCByZW1vdmVkIGNsaWVudHM6ICVsZDsgVG90YWwgcmVuZXdlZCBjbGllbnRzOiAiCiAgICAgICAgICAgICAgICAgICAgICIlbGQiLCBudW1fcmVtb3ZlZCwKICAgICAgICAgICAgICAgICAgICAgY2xpZW50X2xpc3QtPm51bV9jcmVhdGVkIC0gY2xpZW50X2xpc3QtPm51bV9yZW5ld2VkLAogICAgICAgICAgICAgICAgICAgICBjbGllbnRfbGlzdC0+bnVtX3JlbW92ZWQsIGNsaWVudF9saXN0LT5udW1fcmVuZXdlZCk7CiAgICAgICAgZW50cnkgPSBhcHJfcm1tX2FkZHJfZ2V0KGNsaWVudF9ybW0sIGFwcl9ybW1fbWFsbG9jKGNsaWVudF9ybW0sIHNpemVvZihjbGllbnRfZW50cnkpKSk7CiAgICAgICAgaWYgKCFlbnRyeSkgewogICAgICAgICAgICBhcF9sb2dfZXJyb3IoQVBMT0dfTUFSSywgQVBMT0dfRVJSLCAwLCBzLCBBUExPR05PKDAxNzY3KQogICAgICAgICAgICAgICAgICAgICAgICAgInVuYWJsZSB0byBhbGxvY2F0ZSBuZXcgYXV0aF9kaWdlc3QgY2xpZW50Iik7CiAgICAgICAgICAgIGFwcl9nbG9iYWxfbXV0ZXhfdW5sb2NrKGNsaWVudF9sb2NrKTsKICAgICAgICAgICAgcmV0dXJuIE5VTEw7ICAgICAgIC8qIGdpdmUgdXAgKi8KICAgICAgICB9CiAgICB9CgogICAgLyogbm93IGFkZCB0aGUgZW50cnkgKi8KCiAgICBtZW1jcHkoZW50cnksIGluZm8sIHNpemVvZihjbGllbnRfZW50cnkpKTsKICAgIGVudHJ5LT5rZXkgID0ga2V5OwogICAgZW50cnktPm5leHQgPSBjbGllbnRfbGlzdC0+dGFibGVbYnVja2V0XTsKICAgIGNsaWVudF9saXN0LT50YWJsZVtidWNrZXRdID0gZW50cnk7CiAgICBjbGllbnRfbGlzdC0+bnVtX2NyZWF0ZWQrKzsKICAgIGNsaWVudF9saXN0LT5udW1fZW50cmllcysrOwoKICAgIGFwcl9nbG9iYWxfbXV0ZXhfdW5sb2NrKGNsaWVudF9sb2NrKTsKCiAgICBhcF9sb2dfZXJyb3IoQVBMT0dfTUFSSywgQVBMT0dfREVCVUcsIDAsIHMsIEFQTE9HTk8oMDE3NjgpCiAgICAgICAgICAgICAgICAgImFsbG9jYXRlZCBuZXcgY2xpZW50ICVsdSIsIGtleSk7CgogICAgcmV0dXJuIGVudHJ5Owp9CgoKLyoKICogQXV0aG9yaXphdGlvbiBoZWFkZXIgcGFyc2VyIGNvZGUKICovCgovKiBQYXJzZSB0aGUgQXV0aG9yaXphdGlvbiBoZWFkZXIsIGlmIGl0IGV4aXN0cyAqLwpzdGF0aWMgaW50IGdldF9kaWdlc3RfcmVjKHJlcXVlc3RfcmVjICpyLCBkaWdlc3RfaGVhZGVyX3JlYyAqcmVzcCkKewogICAgY29uc3QgY2hhciAqYXV0aF9saW5lOwogICAgYXByX3NpemVfdCBsOwogICAgaW50IHZrID0gMCwgdnYgPSAwOwogICAgY2hhciAqa2V5LCAqdmFsdWU7CgogICAgYXV0aF9saW5lID0gYXByX3RhYmxlX2dldChyLT5oZWFkZXJzX2luLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIChQUk9YWVJFUV9QUk9YWSA9PSByLT5wcm94eXJlcSkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPyAiUHJveHktQXV0aG9yaXphdGlvbiIKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgOiAiQXV0aG9yaXphdGlvbiIpOwogICAgaWYgKCFhdXRoX2xpbmUpIHsKICAgICAgICByZXNwLT5hdXRoX2hkcl9zdHMgPSBOT19IRUFERVI7CiAgICAgICAgcmV0dXJuICFPSzsKICAgIH0KCiAgICByZXNwLT5zY2hlbWUgPSBhcF9nZXR3b3JkX3doaXRlKHItPnBvb2wsICZhdXRoX2xpbmUpOwogICAgaWYgKGFwX2NzdHJfY2FzZWNtcChyZXNwLT5zY2hlbWUsICJEaWdlc3QiKSkgewogICAgICAgIHJlc3AtPmF1dGhfaGRyX3N0cyA9IE5PVF9ESUdFU1Q7CiAgICAgICAgcmV0dXJuICFPSzsKICAgIH0KCiAgICBsID0gc3RybGVuKGF1dGhfbGluZSk7CgogICAga2V5ICAgPSBhcHJfcGFsbG9jKHItPnBvb2wsIGwrMSk7CiAgICB2YWx1ZSA9IGFwcl9wYWxsb2Moci0+cG9vbCwgbCsxKTsKCiAgICB3aGlsZSAoYXV0aF9saW5lWzBdICE9ICdcMCcpIHsKCiAgICAgICAgLyogZmluZCBrZXkgKi8KCiAgICAgICAgd2hpbGUgKGFwcl9pc3NwYWNlKGF1dGhfbGluZVswXSkpIHsKICAgICAgICAgICAgYXV0aF9saW5lKys7CiAgICAgICAgfQogICAgICAgIHZrID0gMDsKICAgICAgICB3aGlsZSAoYXV0aF9saW5lWzBdICE9ICc9JyAmJiBhdXRoX2xpbmVbMF0gIT0gJywnCiAgICAgICAgICAgICAgICYmIGF1dGhfbGluZVswXSAhPSAnXDAnICYmICFhcHJfaXNzcGFjZShhdXRoX2xpbmVbMF0pKSB7CiAgICAgICAgICAgIGtleVt2aysrXSA9ICphdXRoX2xpbmUrKzsKICAgICAgICB9CiAgICAgICAga2V5W3ZrXSA9ICdcMCc7CiAgICAgICAgd2hpbGUgKGFwcl9pc3NwYWNlKGF1dGhfbGluZVswXSkpIHsKICAgICAgICAgICAgYXV0aF9saW5lKys7CiAgICAgICAgfQoKICAgICAgICAvKiBmaW5kIHZhbHVlICovCgogICAgICAgIGlmIChhdXRoX2xpbmVbMF0gPT0gJz0nKSB7CiAgICAgICAgICAgIGF1dGhfbGluZSsrOwogICAgICAgICAgICB3aGlsZSAoYXByX2lzc3BhY2UoYXV0aF9saW5lWzBdKSkgewogICAgICAgICAgICAgICAgYXV0aF9saW5lKys7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHZ2ID0gMDsKICAgICAgICAgICAgaWYgKGF1dGhfbGluZVswXSA9PSAnXCInKSB7ICAgICAgICAgLyogcXVvdGVkIHN0cmluZyAqLwogICAgICAgICAgICAgICAgYXV0aF9saW5lKys7CiAgICAgICAgICAgICAgICB3aGlsZSAoYXV0aF9saW5lWzBdICE9ICdcIicgJiYgYXV0aF9saW5lWzBdICE9ICdcMCcpIHsKICAgICAgICAgICAgICAgICAgICBpZiAoYXV0aF9saW5lWzBdID09ICdcXCcgJiYgYXV0aF9saW5lWzFdICE9ICdcMCcpIHsKICAgICAgICAgICAgICAgICAgICAgICAgYXV0aF9saW5lKys7ICAgICAgICAgICAgLyogZXNjYXBlZCBjaGFyICovCiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIHZhbHVlW3Z2KytdID0gKmF1dGhfbGluZSsrOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaWYgKGF1dGhfbGluZVswXSAhPSAnXDAnKSB7CiAgICAgICAgICAgICAgICAgICAgYXV0aF9saW5lKys7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZSB7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRva2VuICovCiAgICAgICAgICAgICAgICB3aGlsZSAoYXV0aF9saW5lWzBdICE9ICcsJyAmJiBhdXRoX2xpbmVbMF0gIT0gJ1wwJwogICAgICAgICAgICAgICAgICAgICAgICYmICFhcHJfaXNzcGFjZShhdXRoX2xpbmVbMF0pKSB7CiAgICAgICAgICAgICAgICAgICAgdmFsdWVbdnYrK10gPSAqYXV0aF9saW5lKys7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgdmFsdWVbdnZdID0gJ1wwJzsKICAgICAgICB9CgogICAgICAgIHdoaWxlIChhdXRoX2xpbmVbMF0gIT0gJywnICYmIGF1dGhfbGluZVswXSAhPSAnXDAnKSB7CiAgICAgICAgICAgIGF1dGhfbGluZSsrOwogICAgICAgIH0KICAgICAgICBpZiAoYXV0aF9saW5lWzBdICE9ICdcMCcpIHsKICAgICAgICAgICAgYXV0aF9saW5lKys7CiAgICAgICAgfQoKICAgICAgICBpZiAoIWFwX2NzdHJfY2FzZWNtcChrZXksICJ1c2VybmFtZSIpKQogICAgICAgICAgICByZXNwLT51c2VybmFtZSA9IGFwcl9wc3RyZHVwKHItPnBvb2wsIHZhbHVlKTsKICAgICAgICBlbHNlIGlmICghYXBfY3N0cl9jYXNlY21wKGtleSwgInJlYWxtIikpCiAgICAgICAgICAgIHJlc3AtPnJlYWxtID0gYXByX3BzdHJkdXAoci0+cG9vbCwgdmFsdWUpOwogICAgICAgIGVsc2UgaWYgKCFhcF9jc3RyX2Nhc2VjbXAoa2V5LCAibm9uY2UiKSkKICAgICAgICAgICAgcmVzcC0+bm9uY2UgPSBhcHJfcHN0cmR1cChyLT5wb29sLCB2YWx1ZSk7CiAgICAgICAgZWxzZSBpZiAoIWFwX2NzdHJfY2FzZWNtcChrZXksICJ1cmkiKSkKICAgICAgICAgICAgcmVzcC0+dXJpID0gYXByX3BzdHJkdXAoci0+cG9vbCwgdmFsdWUpOwogICAgICAgIGVsc2UgaWYgKCFhcF9jc3RyX2Nhc2VjbXAoa2V5LCAicmVzcG9uc2UiKSkKICAgICAgICAgICAgcmVzcC0+ZGlnZXN0ID0gYXByX3BzdHJkdXAoci0+cG9vbCwgdmFsdWUpOwogICAgICAgIGVsc2UgaWYgKCFhcF9jc3RyX2Nhc2VjbXAoa2V5LCAiYWxnb3JpdGhtIikpCiAgICAgICAgICAgIHJlc3AtPmFsZ29yaXRobSA9IGFwcl9wc3RyZHVwKHItPnBvb2wsIHZhbHVlKTsKICAgICAgICBlbHNlIGlmICghYXBfY3N0cl9jYXNlY21wKGtleSwgImNub25jZSIpKQogICAgICAgICAgICByZXNwLT5jbm9uY2UgPSBhcHJfcHN0cmR1cChyLT5wb29sLCB2YWx1ZSk7CiAgICAgICAgZWxzZSBpZiAoIWFwX2NzdHJfY2FzZWNtcChrZXksICJvcGFxdWUiKSkKICAgICAgICAgICAgcmVzcC0+b3BhcXVlID0gYXByX3BzdHJkdXAoci0+cG9vbCwgdmFsdWUpOwogICAgICAgIGVsc2UgaWYgKCFhcF9jc3RyX2Nhc2VjbXAoa2V5LCAicW9wIikpCiAgICAgICAgICAgIHJlc3AtPm1lc3NhZ2VfcW9wID0gYXByX3BzdHJkdXAoci0+cG9vbCwgdmFsdWUpOwogICAgICAgIGVsc2UgaWYgKCFhcF9jc3RyX2Nhc2VjbXAoa2V5LCAibmMiKSkKICAgICAgICAgICAgcmVzcC0+bm9uY2VfY291bnQgPSBhcHJfcHN0cmR1cChyLT5wb29sLCB2YWx1ZSk7CiAgICB9CgogICAgaWYgKCFyZXNwLT51c2VybmFtZSB8fCAhcmVzcC0+cmVhbG0gfHwgIXJlc3AtPm5vbmNlIHx8ICFyZXNwLT51cmkKICAgICAgICB8fCAhcmVzcC0+ZGlnZXN0CiAgICAgICAgfHwgKHJlc3AtPm1lc3NhZ2VfcW9wICYmICghcmVzcC0+Y25vbmNlIHx8ICFyZXNwLT5ub25jZV9jb3VudCkpKSB7CiAgICAgICAgcmVzcC0+YXV0aF9oZHJfc3RzID0gSU5WQUxJRDsKICAgICAgICByZXR1cm4gIU9LOwogICAgfQoKICAgIGlmIChyZXNwLT5vcGFxdWUpIHsKICAgICAgICByZXNwLT5vcGFxdWVfbnVtID0gKHVuc2lnbmVkIGxvbmcpIHN0cnRvbChyZXNwLT5vcGFxdWUsIE5VTEwsIDE2KTsKICAgIH0KCiAgICByZXNwLT5hdXRoX2hkcl9zdHMgPSBWQUxJRDsKICAgIHJldHVybiBPSzsKfQoKCi8qIEJlY2F1c2UgdGhlIGJyb3dzZXIgbWF5IHByZWVtcHRpdmVseSBzZW5kIGF1dGggaW5mbywgaW5jcmVtZW50aW5nIHRoZQogKiBub25jZS1jb3VudCB3aGVuIGl0IGRvZXMsIGFuZCBiZWNhdXNlIHRoZSBjbGllbnQgZG9lcyBub3QgZ2V0IG5vdGlmaWVkCiAqIGlmIHRoZSBVUkkgZGlkbid0IG5lZWQgYXV0aGVudGljYXRpb24gYWZ0ZXIgYWxsLCB3ZSBuZWVkIHRvIGJlIHN1cmUgdG8KICogdXBkYXRlIHRoZSBub25jZS1jb3VudCBlYWNoIHRpbWUgd2UgcmVjZWl2ZSBhbiBBdXRob3JpemF0aW9uIGhlYWRlciBubwogKiBtYXR0ZXIgd2hhdCB0aGUgZmluYWwgb3V0Y29tZSBvZiB0aGUgcmVxdWVzdC4gRnVydGhlcm1vcmUgdGhpcyBpcyBhCiAqIGNvbnZlbmllbnQgcGxhY2UgdG8gZ2V0IHRoZSByZXF1ZXN0LXVyaSAoYmVmb3JlIGFueSBzdWJyZXF1ZXN0cyBldGMKICogYXJlIGluaXRpYXRlZCkgYW5kIHRvIGluaXRpYWxpemUgdGhlIHJlcXVlc3RfY29uZmlnLgogKgogKiBOb3RlIHRoYXQgdGhpcyBtdXN0IGJlIGNhbGxlZCBhZnRlciBtb2RfcHJveHkgaGFkIGl0cyBnbyBzbyB0aGF0CiAqIHItPnByb3h5cmVxIGlzIHNldCBjb3JyZWN0bHkuCiAqLwpzdGF0aWMgaW50IHBhcnNlX2hkcl9hbmRfdXBkYXRlX25jKHJlcXVlc3RfcmVjICpyKQp7CiAgICBkaWdlc3RfaGVhZGVyX3JlYyAqcmVzcDsKICAgIGludCByZXM7CgogICAgaWYgKCFhcF9pc19pbml0aWFsX3JlcShyKSkgewogICAgICAgIHJldHVybiBERUNMSU5FRDsKICAgIH0KCiAgICByZXNwID0gYXByX3BjYWxsb2Moci0+cG9vbCwgc2l6ZW9mKGRpZ2VzdF9oZWFkZXJfcmVjKSk7CiAgICByZXNwLT5yYXdfcmVxdWVzdF91cmkgPSByLT51bnBhcnNlZF91cmk7CiAgICByZXNwLT5wc2RfcmVxdWVzdF91cmkgPSAmci0+cGFyc2VkX3VyaTsKICAgIHJlc3AtPm5lZWRlZF9hdXRoID0gMDsKICAgIHJlc3AtPm1ldGhvZCA9IHItPm1ldGhvZDsKICAgIGFwX3NldF9tb2R1bGVfY29uZmlnKHItPnJlcXVlc3RfY29uZmlnLCAmYXV0aF9kaWdlc3RfbW9kdWxlLCByZXNwKTsKCiAgICByZXMgPSBnZXRfZGlnZXN0X3JlYyhyLCByZXNwKTsKICAgIHJlc3AtPmNsaWVudCA9IGdldF9jbGllbnQocmVzcC0+b3BhcXVlX251bSwgcik7CiAgICBpZiAocmVzID09IE9LICYmIHJlc3AtPmNsaWVudCkgewogICAgICAgIHJlc3AtPmNsaWVudC0+bm9uY2VfY291bnQrKzsKICAgIH0KCiAgICByZXR1cm4gREVDTElORUQ7Cn0KCgovKgogKiBOb25jZSBnZW5lcmF0aW9uIGNvZGUKICovCgovKiBUaGUgaGFzaCBwYXJ0IG9mIHRoZSBub25jZSBpcyBhIFNIQS0xIGhhc2ggb2YgdGhlIHRpbWUsIHJlYWxtLCBzZXJ2ZXIgaG9zdAogKiBhbmQgcG9ydCwgb3BhcXVlLCBhbmQgb3VyIHNlY3JldC4KICovCnN0YXRpYyB2b2lkIGdlbl9ub25jZV9oYXNoKGNoYXIgKmhhc2gsIGNvbnN0IGNoYXIgKnRpbWVzdHIsIGNvbnN0IGNoYXIgKm9wYXF1ZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3Qgc2VydmVyX3JlYyAqc2VydmVyLAogICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBkaWdlc3RfY29uZmlnX3JlYyAqY29uZiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGNoYXIgKnJlYWxtKQp7CiAgICB1bnNpZ25lZCBjaGFyIHNoYTFbQVBSX1NIQTFfRElHRVNUU0laRV07CiAgICBhcHJfc2hhMV9jdHhfdCBjdHg7CgogICAgbWVtY3B5KCZjdHgsICZjb25mLT5ub25jZV9jdHgsIHNpemVvZihjdHgpKTsKICAgIC8qCiAgICBhcHJfc2hhMV91cGRhdGVfYmluYXJ5KCZjdHgsIChjb25zdCB1bnNpZ25lZCBjaGFyICopIHNlcnZlci0+c2VydmVyX2hvc3RuYW1lLAogICAgICAgICAgICAgICAgICAgICAgICAgc3RybGVuKHNlcnZlci0+c2VydmVyX2hvc3RuYW1lKSk7CiAgICBhcHJfc2hhMV91cGRhdGVfYmluYXJ5KCZjdHgsIChjb25zdCB1bnNpZ25lZCBjaGFyICopICZzZXJ2ZXItPnBvcnQsCiAgICAgICAgICAgICAgICAgICAgICAgICBzaXplb2Yoc2VydmVyLT5wb3J0KSk7CiAgICAgKi8KCiAgICBhcHJfc2hhMV91cGRhdGVfYmluYXJ5KCZjdHgsIChjb25zdCB1bnNpZ25lZCBjaGFyICopIHJlYWxtLCBzdHJsZW4ocmVhbG0pKTsKCiAgICBhcHJfc2hhMV91cGRhdGVfYmluYXJ5KCZjdHgsIChjb25zdCB1bnNpZ25lZCBjaGFyICopIHRpbWVzdHIsIHN0cmxlbih0aW1lc3RyKSk7CiAgICBpZiAob3BhcXVlKSB7CiAgICAgICAgYXByX3NoYTFfdXBkYXRlX2JpbmFyeSgmY3R4LCAoY29uc3QgdW5zaWduZWQgY2hhciAqKSBvcGFxdWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RybGVuKG9wYXF1ZSkpOwogICAgfQogICAgYXByX3NoYTFfZmluYWwoc2hhMSwgJmN0eCk7CgogICAgYXBfYmluMmhleChzaGExLCBBUFJfU0hBMV9ESUdFU1RTSVpFLCBoYXNoKTsKfQoKCi8qIFRoZSBub25jZSBoYXMgdGhlIGZvcm1hdCBiNjQodGltZSkraGFzaCAuCiAqLwpzdGF0aWMgY29uc3QgY2hhciAqZ2VuX25vbmNlKGFwcl9wb29sX3QgKnAsIGFwcl90aW1lX3Qgbm93LCBjb25zdCBjaGFyICpvcGFxdWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3Qgc2VydmVyX3JlYyAqc2VydmVyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGRpZ2VzdF9jb25maWdfcmVjICpjb25mLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGNoYXIgKnJlYWxtKQp7CiAgICBjaGFyICpub25jZSA9IGFwcl9wYWxsb2MocCwgTk9OQ0VfTEVOKzEpOwogICAgdGltZV9yZWMgdDsKCiAgICBpZiAoY29uZi0+bm9uY2VfbGlmZXRpbWUgIT0gMCkgewogICAgICAgIHQudGltZSA9IG5vdzsKICAgIH0KICAgIGVsc2UgaWYgKG90bl9jb3VudGVyKSB7CiAgICAgICAgLyogdGhpcyBjb3VudGVyIGlzIG5vdCBzeW5jaCdkLCBiZWNhdXNlIGl0IGRvZXNuJ3QgcmVhbGx5IG1hdHRlcgogICAgICAgICAqIGlmIGl0IGNvdW50cyBleGFjdGx5LgogICAgICAgICAqLwogICAgICAgIHQudGltZSA9ICgqb3RuX2NvdW50ZXIpKys7CiAgICB9CiAgICBlbHNlIHsKICAgICAgICAvKiBYWFg6IFdIQVQgSVMgVEhJUyBDT05TVEFOVD8gKi8KICAgICAgICB0LnRpbWUgPSA0MjsKICAgIH0KICAgIGFwcl9iYXNlNjRfZW5jb2RlX2JpbmFyeShub25jZSwgdC5hcnIsIHNpemVvZih0LmFycikpOwogICAgZ2VuX25vbmNlX2hhc2gobm9uY2UrTk9OQ0VfVElNRV9MRU4sIG5vbmNlLCBvcGFxdWUsIHNlcnZlciwgY29uZiwgcmVhbG0pOwoKICAgIHJldHVybiBub25jZTsKfQoKCi8qCiAqIE9wYXF1ZSBhbmQgaGFzaC10YWJsZSBtYW5hZ2VtZW50CiAqLwoKLyoKICogR2VuZXJhdGUgYSBuZXcgY2xpZW50IGVudHJ5LCBhZGQgaXQgdG8gdGhlIGxpc3QsIGFuZCByZXR1cm4gdGhlCiAqIGVudHJ5LiBSZXR1cm5zIE5VTEwgaWYgZmFpbGVkLgogKi8Kc3RhdGljIGNsaWVudF9lbnRyeSAqZ2VuX2NsaWVudChjb25zdCByZXF1ZXN0X3JlYyAqcikKewogICAgdW5zaWduZWQgbG9uZyBvcDsKICAgIGNsaWVudF9lbnRyeSBuZXdfZW50cnkgPSB7IDAsIE5VTEwsIDAsICIiIH0sICplbnRyeTsKCiAgICBpZiAoIW9wYXF1ZV9jbnRyKSB7CiAgICAgICAgcmV0dXJuIE5VTEw7CiAgICB9CgogICAgYXByX2dsb2JhbF9tdXRleF9sb2NrKG9wYXF1ZV9sb2NrKTsKICAgIG9wID0gKCpvcGFxdWVfY250cikrKzsKICAgIGFwcl9nbG9iYWxfbXV0ZXhfdW5sb2NrKG9wYXF1ZV9sb2NrKTsKCiAgICBpZiAoIShlbnRyeSA9IGFkZF9jbGllbnQob3AsICZuZXdfZW50cnksIHItPnNlcnZlcikpKSB7CiAgICAgICAgYXBfbG9nX3JlcnJvcihBUExPR19NQVJLLCBBUExPR19FUlIsIDAsIHIsIEFQTE9HTk8oMDE3NjkpCiAgICAgICAgICAgICAgICAgICAgICAiZmFpbGVkIHRvIGFsbG9jYXRlIGNsaWVudCBlbnRyeSAtIGlnbm9yaW5nIGNsaWVudCIpOwogICAgICAgIHJldHVybiBOVUxMOwogICAgfQoKICAgIHJldHVybiBlbnRyeTsKfQoKCi8qCiAqIEF1dGhvcml6YXRpb24gY2hhbGxlbmdlIGdlbmVyYXRpb24gY29kZSAoZm9yIFdXVy1BdXRoZW50aWNhdGUpCiAqLwoKc3RhdGljIGNvbnN0IGNoYXIgKmx0b3goYXByX3Bvb2xfdCAqcCwgdW5zaWduZWQgbG9uZyBudW0pCnsKICAgIGlmIChudW0gIT0gMCkgewogICAgICAgIHJldHVybiBhcHJfcHNwcmludGYocCwgIiVseCIsIG51bSk7CiAgICB9CiAgICBlbHNlIHsKICAgICAgICByZXR1cm4gIiI7CiAgICB9Cn0KCnN0YXRpYyB2b2lkIG5vdGVfZGlnZXN0X2F1dGhfZmFpbHVyZShyZXF1ZXN0X3JlYyAqciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGRpZ2VzdF9jb25maWdfcmVjICpjb25mLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGlnZXN0X2hlYWRlcl9yZWMgKnJlc3AsIGludCBzdGFsZSkKewogICAgY29uc3QgY2hhciAgICpxb3AsICpvcGFxdWUsICpvcGFxdWVfcGFyYW0sICpkb21haW4sICpub25jZTsKCiAgICAvKiBTZXR1cCBxb3AgKi8KICAgIGlmIChhcHJfaXNfZW1wdHlfYXJyYXkoY29uZi0+cW9wX2xpc3QpKSB7CiAgICAgICAgcW9wID0gIiwgcW9wPVwiYXV0aFwiIjsKICAgIH0KICAgIGVsc2UgaWYgKCFhcF9jc3RyX2Nhc2VjbXAoKihjb25zdCBjaGFyICoqKShjb25mLT5xb3BfbGlzdC0+ZWx0cyksICJub25lIikpIHsKICAgICAgICBxb3AgPSAiIjsKICAgIH0KICAgIGVsc2UgewogICAgICAgIHFvcCA9IGFwcl9wc3RyY2F0KHItPnBvb2wsICIsIHFvcD1cIiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXByX2FycmF5X3BzdHJjYXQoci0+cG9vbCwgY29uZi0+cW9wX2xpc3QsICcsJyksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIlwiIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBOVUxMKTsKICAgIH0KCiAgICAvKiBTZXR1cCBvcGFxdWUgKi8KCiAgICBpZiAocmVzcC0+b3BhcXVlID09IE5VTEwpIHsKICAgICAgICAvKiBuZXcgY2xpZW50ICovCiAgICAgICAgaWYgKChjb25mLT5jaGVja19uYyB8fCBjb25mLT5ub25jZV9saWZldGltZSA9PSAwKQogICAgICAgICAgICAmJiAocmVzcC0+Y2xpZW50ID0gZ2VuX2NsaWVudChyKSkgIT0gTlVMTCkgewogICAgICAgICAgICBvcGFxdWUgPSBsdG94KHItPnBvb2wsIHJlc3AtPmNsaWVudC0+a2V5KTsKICAgICAgICB9CiAgICAgICAgZWxzZSB7CiAgICAgICAgICAgIG9wYXF1ZSA9ICIiOyAgICAgICAgICAgICAgICAvKiBvcGFxdWUgbm90IG5lZWRlZCAqLwogICAgICAgIH0KICAgIH0KICAgIGVsc2UgaWYgKHJlc3AtPmNsaWVudCA9PSBOVUxMKSB7CiAgICAgICAgLyogY2xpZW50IGluZm8gd2FzIGdjJ2QgKi8KICAgICAgICByZXNwLT5jbGllbnQgPSBnZW5fY2xpZW50KHIpOwogICAgICAgIGlmIChyZXNwLT5jbGllbnQgIT0gTlVMTCkgewogICAgICAgICAgICBvcGFxdWUgPSBsdG94KHItPnBvb2wsIHJlc3AtPmNsaWVudC0+a2V5KTsKICAgICAgICAgICAgc3RhbGUgPSAxOwogICAgICAgICAgICBjbGllbnRfbGlzdC0+bnVtX3JlbmV3ZWQrKzsKICAgICAgICB9CiAgICAgICAgZWxzZSB7CiAgICAgICAgICAgIG9wYXF1ZSA9ICIiOyAgICAgICAgICAgICAgICAvKiA/Pz8gKi8KICAgICAgICB9CiAgICB9CiAgICBlbHNlIHsKICAgICAgICBvcGFxdWUgPSByZXNwLT5vcGFxdWU7CiAgICAgICAgLyogd2UncmUgZ2VuZXJhdGluZyBhIG5ldyBub25jZSwgc28gcmVzZXQgdGhlIG5vbmNlLWNvdW50ICovCiAgICAgICAgcmVzcC0+Y2xpZW50LT5ub25jZV9jb3VudCA9IDA7CiAgICB9CgogICAgaWYgKG9wYXF1ZVswXSkgewogICAgICAgIG9wYXF1ZV9wYXJhbSA9IGFwcl9wc3RyY2F0KHItPnBvb2wsICIsIG9wYXF1ZT1cIiIsIG9wYXF1ZSwgIlwiIiwgTlVMTCk7CiAgICB9CiAgICBlbHNlIHsKICAgICAgICBvcGFxdWVfcGFyYW0gPSBOVUxMOwogICAgfQoKICAgIC8qIFNldHVwIG5vbmNlICovCgogICAgbm9uY2UgPSBnZW5fbm9uY2Uoci0+cG9vbCwgci0+cmVxdWVzdF90aW1lLCBvcGFxdWUsIHItPnNlcnZlciwgY29uZiwgYXBfYXV0aF9uYW1lKHIpKTsKICAgIGlmIChyZXNwLT5jbGllbnQgJiYgY29uZi0+bm9uY2VfbGlmZXRpbWUgPT0gMCkgewogICAgICAgIG1lbWNweShyZXNwLT5jbGllbnQtPmxhc3Rfbm9uY2UsIG5vbmNlLCBOT05DRV9MRU4rMSk7CiAgICB9CgogICAgLyogc2V0dXAgZG9tYWluIGF0dHJpYnV0ZS4gV2Ugd2FudCB0byBzZW5kIHRoaXMgYXR0cmlidXRlIHdoZXJldmVyCiAgICAgKiBwb3NzaWJsZSBzbyB0aGF0IHRoZSBjbGllbnQgd29uJ3Qgc2VuZCB0aGUgQXV0aG9yaXphdGlvbiBoZWFkZXIKICAgICAqIHVubmVjZXNzYXJpbHkgKGl0J3MgdXN1YWxseSA+IDIwMCBieXRlcyEpLgogICAgICovCgoKICAgIC8qIGRvbid0IHNlbmQgZG9tYWluCiAgICAgKiAtIGZvciBwcm94eSByZXF1ZXN0cwogICAgICogLSBpZiBpdCdzIG5vdCBzcGVjaWZpZWQKICAgICAqLwogICAgaWYgKHItPnByb3h5cmVxIHx8ICFjb25mLT51cmlfbGlzdCkgewogICAgICAgIGRvbWFpbiA9IE5VTEw7CiAgICB9CiAgICBlbHNlIHsKICAgICAgICBkb21haW4gPSBjb25mLT51cmlfbGlzdDsKICAgIH0KCiAgICBhcHJfdGFibGVfbWVyZ2VuKHItPmVycl9oZWFkZXJzX291dCwKICAgICAgICAgICAgICAgICAgICAgKFBST1hZUkVRX1BST1hZID09IHItPnByb3h5cmVxKQogICAgICAgICAgICAgICAgICAgICAgICAgPyAiUHJveHktQXV0aGVudGljYXRlIiA6ICJXV1ctQXV0aGVudGljYXRlIiwKICAgICAgICAgICAgICAgICAgICAgYXByX3BzcHJpbnRmKHItPnBvb2wsICJEaWdlc3QgcmVhbG09XCIlc1wiLCAiCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAibm9uY2U9XCIlc1wiLCBhbGdvcml0aG09JXMlcyVzJXMlcyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhcF9hdXRoX25hbWUociksIG5vbmNlLCBjb25mLT5hbGdvcml0aG0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvcGFxdWVfcGFyYW0gPyBvcGFxdWVfcGFyYW0gOiAiIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRvbWFpbiA/IGRvbWFpbiA6ICIiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RhbGUgPyAiLCBzdGFsZT10cnVlIiA6ICIiLCBxb3ApKTsKCn0KCnN0YXRpYyBpbnQgaG9va19ub3RlX2RpZ2VzdF9hdXRoX2ZhaWx1cmUocmVxdWVzdF9yZWMgKnIsIGNvbnN0IGNoYXIgKmF1dGhfdHlwZSkKewogICAgcmVxdWVzdF9yZWMgKm1haW5yZXE7CiAgICBkaWdlc3RfaGVhZGVyX3JlYyAqcmVzcDsKICAgIGRpZ2VzdF9jb25maWdfcmVjICpjb25mOwoKICAgIGlmIChhcF9jc3RyX2Nhc2VjbXAoYXV0aF90eXBlLCAiRGlnZXN0IikpCiAgICAgICAgcmV0dXJuIERFQ0xJTkVEOwoKICAgIC8qIGdldCB0aGUgY2xpZW50IHJlc3BvbnNlIGFuZCBtYXJrICovCgogICAgbWFpbnJlcSA9IHI7CiAgICB3aGlsZSAobWFpbnJlcS0+bWFpbiAhPSBOVUxMKSB7CiAgICAgICAgbWFpbnJlcSA9IG1haW5yZXEtPm1haW47CiAgICB9CiAgICB3aGlsZSAobWFpbnJlcS0+cHJldiAhPSBOVUxMKSB7CiAgICAgICAgbWFpbnJlcSA9IG1haW5yZXEtPnByZXY7CiAgICB9CiAgICByZXNwID0gKGRpZ2VzdF9oZWFkZXJfcmVjICopIGFwX2dldF9tb2R1bGVfY29uZmlnKG1haW5yZXEtPnJlcXVlc3RfY29uZmlnLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmYXV0aF9kaWdlc3RfbW9kdWxlKTsKICAgIHJlc3AtPm5lZWRlZF9hdXRoID0gMTsKCgogICAgLyogZ2V0IG91ciBjb25mICovCgogICAgY29uZiA9IChkaWdlc3RfY29uZmlnX3JlYyAqKSBhcF9nZXRfbW9kdWxlX2NvbmZpZyhyLT5wZXJfZGlyX2NvbmZpZywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJmF1dGhfZGlnZXN0X21vZHVsZSk7CgogICAgbm90ZV9kaWdlc3RfYXV0aF9mYWlsdXJlKHIsIGNvbmYsIHJlc3AsIDApOwoKICAgIHJldHVybiBPSzsKfQoKCi8qCiAqIEF1dGhvcml6YXRpb24gaGVhZGVyIHZlcmlmaWNhdGlvbiBjb2RlCiAqLwoKc3RhdGljIGF1dGhuX3N0YXR1cyBnZXRfaGFzaChyZXF1ZXN0X3JlYyAqciwgY29uc3QgY2hhciAqdXNlciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkaWdlc3RfY29uZmlnX3JlYyAqY29uZikKewogICAgYXV0aG5fc3RhdHVzIGF1dGhfcmVzdWx0OwogICAgY2hhciAqcGFzc3dvcmQ7CiAgICBhdXRobl9wcm92aWRlcl9saXN0ICpjdXJyZW50X3Byb3ZpZGVyOwoKICAgIGN1cnJlbnRfcHJvdmlkZXIgPSBjb25mLT5wcm92aWRlcnM7CiAgICBkbyB7CiAgICAgICAgY29uc3QgYXV0aG5fcHJvdmlkZXIgKnByb3ZpZGVyOwoKICAgICAgICAvKiBGb3Igbm93LCBpZiBhIHByb3ZpZGVyIGlzbid0IHNldCwgd2UnbGwgYmUgbmljZSBhbmQgdXNlIHRoZSBmaWxlCiAgICAgICAgICogcHJvdmlkZXIuCiAgICAgICAgICovCiAgICAgICAgaWYgKCFjdXJyZW50X3Byb3ZpZGVyKSB7CiAgICAgICAgICAgIHByb3ZpZGVyID0gYXBfbG9va3VwX3Byb3ZpZGVyKEFVVEhOX1BST1ZJREVSX0dST1VQLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBVVRITl9ERUZBVUxUX1BST1ZJREVSLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBVVRITl9QUk9WSURFUl9WRVJTSU9OKTsKCiAgICAgICAgICAgIGlmICghcHJvdmlkZXIgfHwgIXByb3ZpZGVyLT5nZXRfcmVhbG1faGFzaCkgewogICAgICAgICAgICAgICAgYXBfbG9nX3JlcnJvcihBUExPR19NQVJLLCBBUExPR19FUlIsIDAsIHIsIEFQTE9HTk8oMDE3NzApCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJObyBBdXRobiBwcm92aWRlciBjb25maWd1cmVkIik7CiAgICAgICAgICAgICAgICBhdXRoX3Jlc3VsdCA9IEFVVEhfR0VORVJBTF9FUlJPUjsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGFwcl90YWJsZV9zZXRuKHItPm5vdGVzLCBBVVRITl9QUk9WSURFUl9OQU1FX05PVEUsIEFVVEhOX0RFRkFVTFRfUFJPVklERVIpOwogICAgICAgIH0KICAgICAgICBlbHNlIHsKICAgICAgICAgICAgcHJvdmlkZXIgPSBjdXJyZW50X3Byb3ZpZGVyLT5wcm92aWRlcjsKICAgICAgICAgICAgYXByX3RhYmxlX3NldG4oci0+bm90ZXMsIEFVVEhOX1BST1ZJREVSX05BTUVfTk9URSwgY3VycmVudF9wcm92aWRlci0+cHJvdmlkZXJfbmFtZSk7CiAgICAgICAgfQoKCiAgICAgICAgLyogV2UgZXhwZWN0IHRoZSBwYXNzd29yZCB0byBiZSBtZDUgaGFzaCBvZiB1c2VyOnJlYWxtOnBhc3N3b3JkICovCiAgICAgICAgYXV0aF9yZXN1bHQgPSBwcm92aWRlci0+Z2V0X3JlYWxtX2hhc2gociwgdXNlciwgYXBfYXV0aF9uYW1lKHIpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZwYXNzd29yZCk7CgogICAgICAgIGFwcl90YWJsZV91bnNldChyLT5ub3RlcywgQVVUSE5fUFJPVklERVJfTkFNRV9OT1RFKTsKCiAgICAgICAgLyogU29tZXRoaW5nIG9jY3VyZWQuICBTdG9wIGNoZWNraW5nLiAqLwogICAgICAgIGlmIChhdXRoX3Jlc3VsdCAhPSBBVVRIX1VTRVJfTk9UX0ZPVU5EKSB7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIH0KCiAgICAgICAgLyogSWYgd2UncmUgbm90IHJlYWxseSBjb25maWd1cmVkIGZvciBwcm92aWRlcnMsIHN0b3Agbm93LiAqLwogICAgICAgIGlmICghY29uZi0+cHJvdmlkZXJzKSB7CiAgICAgICAgICAgYnJlYWs7CiAgICAgICAgfQoKICAgICAgICBjdXJyZW50X3Byb3ZpZGVyID0gY3VycmVudF9wcm92aWRlci0+bmV4dDsKICAgIH0gd2hpbGUgKGN1cnJlbnRfcHJvdmlkZXIpOwoKICAgIGlmIChhdXRoX3Jlc3VsdCA9PSBBVVRIX1VTRVJfRk9VTkQpIHsKICAgICAgICBjb25mLT5oYTEgPSBwYXNzd29yZDsKICAgIH0KCiAgICByZXR1cm4gYXV0aF9yZXN1bHQ7Cn0KCnN0YXRpYyBpbnQgY2hlY2tfbmMoY29uc3QgcmVxdWVzdF9yZWMgKnIsIGNvbnN0IGRpZ2VzdF9oZWFkZXJfcmVjICpyZXNwLAogICAgICAgICAgICAgICAgICAgIGNvbnN0IGRpZ2VzdF9jb25maWdfcmVjICpjb25mKQp7CiAgICB1bnNpZ25lZCBsb25nIG5jOwogICAgY29uc3QgY2hhciAqc25jID0gcmVzcC0+bm9uY2VfY291bnQ7CiAgICBjaGFyICplbmRwdHI7CgogICAgaWYgKGNvbmYtPmNoZWNrX25jICYmICFjbGllbnRfc2htKSB7CiAgICAgICAgLyogU2hvdWxkbid0IGhhcHBlbiwgYnV0IGp1c3QgaW4gY2FzZS4uLiAqLwogICAgICAgIGFwX2xvZ19yZXJyb3IoQVBMT0dfTUFSSywgQVBMT0dfV0FSTklORywgMCwgciwgQVBMT0dOTygwMTc3MSkKICAgICAgICAgICAgICAgICAgICAgICJjYW5ub3QgY2hlY2sgbm9uY2UgY291bnQgd2l0aG91dCBzaGFyZWQgbWVtb3J5Iik7CiAgICAgICAgcmV0dXJuIE9LOwogICAgfQoKICAgIGlmICghY29uZi0+Y2hlY2tfbmMgfHwgIWNsaWVudF9zaG0pIHsKICAgICAgICByZXR1cm4gT0s7CiAgICB9CgogICAgaWYgKCFhcHJfaXNfZW1wdHlfYXJyYXkoY29uZi0+cW9wX2xpc3QpICYmCiAgICAgICAgIWFwX2NzdHJfY2FzZWNtcCgqKGNvbnN0IGNoYXIgKiopKGNvbmYtPnFvcF9saXN0LT5lbHRzKSwgIm5vbmUiKSkgewogICAgICAgIC8qIHFvcCBpcyBub25lLCBjbGllbnQgbXVzdCBub3Qgc2VuZCBhIG5vbmNlIGNvdW50ICovCiAgICAgICAgaWYgKHNuYyAhPSBOVUxMKSB7CiAgICAgICAgICAgIGFwX2xvZ19yZXJyb3IoQVBMT0dfTUFSSywgQVBMT0dfRVJSLCAwLCByLCBBUExPR05PKDAxNzcyKQogICAgICAgICAgICAgICAgICAgICAgICAgICJpbnZhbGlkIG5jICVzIHJlY2VpdmVkIC0gbm8gbm9uY2UgY291bnQgYWxsb3dlZCB3aGVuIHFvcD1ub25lIiwKICAgICAgICAgICAgICAgICAgICAgICAgICBzbmMpOwogICAgICAgICAgICByZXR1cm4gIU9LOwogICAgICAgIH0KICAgICAgICAvKiBxb3AgaXMgbm9uZSwgY2Fubm90IGNoZWNrIG5vbmNlIGNvdW50ICovCiAgICAgICAgcmV0dXJuIE9LOwogICAgfQoKICAgIG5jID0gc3RydG9sKHNuYywgJmVuZHB0ciwgMTYpOwogICAgaWYgKGVuZHB0ciA8IChzbmMrc3RybGVuKHNuYykpICYmICFhcHJfaXNzcGFjZSgqZW5kcHRyKSkgewogICAgICAgIGFwX2xvZ19yZXJyb3IoQVBMT0dfTUFSSywgQVBMT0dfRVJSLCAwLCByLCBBUExPR05PKDAxNzczKQogICAgICAgICAgICAgICAgICAgICAgImludmFsaWQgbmMgJXMgcmVjZWl2ZWQgLSBub3QgYSBudW1iZXIiLCBzbmMpOwogICAgICAgIHJldHVybiAhT0s7CiAgICB9CgogICAgaWYgKCFyZXNwLT5jbGllbnQpIHsKICAgICAgICByZXR1cm4gIU9LOwogICAgfQoKICAgIGlmIChuYyAhPSByZXNwLT5jbGllbnQtPm5vbmNlX2NvdW50KSB7CiAgICAgICAgYXBfbG9nX3JlcnJvcihBUExPR19NQVJLLCBBUExPR19FUlIsIDAsIHIsIEFQTE9HTk8oMDE3NzQpCiAgICAgICAgICAgICAgICAgICAgICAiV2FybmluZywgcG9zc2libGUgcmVwbGF5IGF0dGFjazogbm9uY2UtY291bnQgIgogICAgICAgICAgICAgICAgICAgICAgImNoZWNrIGZhaWxlZDogJWx1ICE9ICVsdSIsIG5jLAogICAgICAgICAgICAgICAgICAgICAgcmVzcC0+Y2xpZW50LT5ub25jZV9jb3VudCk7CiAgICAgICAgcmV0dXJuICFPSzsKICAgIH0KCiAgICByZXR1cm4gT0s7Cn0KCnN0YXRpYyBpbnQgY2hlY2tfbm9uY2UocmVxdWVzdF9yZWMgKnIsIGRpZ2VzdF9oZWFkZXJfcmVjICpyZXNwLAogICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGRpZ2VzdF9jb25maWdfcmVjICpjb25mKQp7CiAgICBhcHJfdGltZV90IGR0OwogICAgdGltZV9yZWMgbm9uY2VfdGltZTsKICAgIGNoYXIgdG1wLCBoYXNoW05PTkNFX0hBU0hfTEVOKzFdOwoKICAgIGlmIChzdHJsZW4ocmVzcC0+bm9uY2UpICE9IE5PTkNFX0xFTikgewogICAgICAgIGFwX2xvZ19yZXJyb3IoQVBMT0dfTUFSSywgQVBMT0dfRVJSLCAwLCByLCBBUExPR05PKDAxNzc1KQogICAgICAgICAgICAgICAgICAgICAgImludmFsaWQgbm9uY2UgJXMgcmVjZWl2ZWQgLSBsZW5ndGggaXMgbm90ICVkIiwKICAgICAgICAgICAgICAgICAgICAgIHJlc3AtPm5vbmNlLCBOT05DRV9MRU4pOwogICAgICAgIG5vdGVfZGlnZXN0X2F1dGhfZmFpbHVyZShyLCBjb25mLCByZXNwLCAxKTsKICAgICAgICByZXR1cm4gSFRUUF9VTkFVVEhPUklaRUQ7CiAgICB9CgogICAgdG1wID0gcmVzcC0+bm9uY2VbTk9OQ0VfVElNRV9MRU5dOwogICAgcmVzcC0+bm9uY2VbTk9OQ0VfVElNRV9MRU5dID0gJ1wwJzsKICAgIGFwcl9iYXNlNjRfZGVjb2RlX2JpbmFyeShub25jZV90aW1lLmFyciwgcmVzcC0+bm9uY2UpOwogICAgZ2VuX25vbmNlX2hhc2goaGFzaCwgcmVzcC0+bm9uY2UsIHJlc3AtPm9wYXF1ZSwgci0+c2VydmVyLCBjb25mLCBhcF9hdXRoX25hbWUocikpOwogICAgcmVzcC0+bm9uY2VbTk9OQ0VfVElNRV9MRU5dID0gdG1wOwogICAgcmVzcC0+bm9uY2VfdGltZSA9IG5vbmNlX3RpbWUudGltZTsKCiAgICBpZiAoc3RyY21wKGhhc2gsIHJlc3AtPm5vbmNlK05PTkNFX1RJTUVfTEVOKSkgewogICAgICAgIGFwX2xvZ19yZXJyb3IoQVBMT0dfTUFSSywgQVBMT0dfRVJSLCAwLCByLCBBUExPR05PKDAxNzc2KQogICAgICAgICAgICAgICAgICAgICAgImludmFsaWQgbm9uY2UgJXMgcmVjZWl2ZWQgLSBoYXNoIGlzIG5vdCAlcyIsCiAgICAgICAgICAgICAgICAgICAgICByZXNwLT5ub25jZSwgaGFzaCk7CiAgICAgICAgbm90ZV9kaWdlc3RfYXV0aF9mYWlsdXJlKHIsIGNvbmYsIHJlc3AsIDEpOwogICAgICAgIHJldHVybiBIVFRQX1VOQVVUSE9SSVpFRDsKICAgIH0KCiAgICBkdCA9IHItPnJlcXVlc3RfdGltZSAtIG5vbmNlX3RpbWUudGltZTsKICAgIGlmIChjb25mLT5ub25jZV9saWZldGltZSA+IDAgJiYgZHQgPCAwKSB7CiAgICAgICAgYXBfbG9nX3JlcnJvcihBUExPR19NQVJLLCBBUExPR19FUlIsIDAsIHIsIEFQTE9HTk8oMDE3NzcpCiAgICAgICAgICAgICAgICAgICAgICAiaW52YWxpZCBub25jZSAlcyByZWNlaXZlZCAtIHVzZXIgYXR0ZW1wdGVkICIKICAgICAgICAgICAgICAgICAgICAgICJ0aW1lIHRyYXZlbCIsIHJlc3AtPm5vbmNlKTsKICAgICAgICBub3RlX2RpZ2VzdF9hdXRoX2ZhaWx1cmUociwgY29uZiwgcmVzcCwgMSk7CiAgICAgICAgcmV0dXJuIEhUVFBfVU5BVVRIT1JJWkVEOwogICAgfQoKICAgIGlmIChjb25mLT5ub25jZV9saWZldGltZSA+IDApIHsKICAgICAgICBpZiAoZHQgPiBjb25mLT5ub25jZV9saWZldGltZSkgewogICAgICAgICAgICBhcF9sb2dfcmVycm9yKEFQTE9HX01BUkssIEFQTE9HX0lORk8sIDAsciwgQVBMT0dOTygwMTc3OCkKICAgICAgICAgICAgICAgICAgICAgICAgICAidXNlciAlczogbm9uY2UgZXhwaXJlZCAoJS4yZiBzZWNvbmRzIG9sZCAiCiAgICAgICAgICAgICAgICAgICAgICAgICAgIi0gbWF4IGxpZmV0aW1lICUuMmYpIC0gc2VuZGluZyBuZXcgbm9uY2UiLAogICAgICAgICAgICAgICAgICAgICAgICAgIHItPnVzZXIsIChkb3VibGUpYXByX3RpbWVfc2VjKGR0KSwKICAgICAgICAgICAgICAgICAgICAgICAgICAoZG91YmxlKWFwcl90aW1lX3NlYyhjb25mLT5ub25jZV9saWZldGltZSkpOwogICAgICAgICAgICBub3RlX2RpZ2VzdF9hdXRoX2ZhaWx1cmUociwgY29uZiwgcmVzcCwgMSk7CiAgICAgICAgICAgIHJldHVybiBIVFRQX1VOQVVUSE9SSVpFRDsKICAgICAgICB9CiAgICB9CiAgICBlbHNlIGlmIChjb25mLT5ub25jZV9saWZldGltZSA9PSAwICYmIHJlc3AtPmNsaWVudCkgewogICAgICAgIGlmIChtZW1jbXAocmVzcC0+Y2xpZW50LT5sYXN0X25vbmNlLCByZXNwLT5ub25jZSwgTk9OQ0VfTEVOKSkgewogICAgICAgICAgICBhcF9sb2dfcmVycm9yKEFQTE9HX01BUkssIEFQTE9HX0lORk8sIDAsIHIsIEFQTE9HTk8oMDE3NzkpCiAgICAgICAgICAgICAgICAgICAgICAgICAgInVzZXIgJXM6IG9uZS10aW1lLW5vbmNlIG1pc21hdGNoIC0gc2VuZGluZyAiCiAgICAgICAgICAgICAgICAgICAgICAgICAgIm5ldyBub25jZSIsIHItPnVzZXIpOwogICAgICAgICAgICBub3RlX2RpZ2VzdF9hdXRoX2ZhaWx1cmUociwgY29uZiwgcmVzcCwgMSk7CiAgICAgICAgICAgIHJldHVybiBIVFRQX1VOQVVUSE9SSVpFRDsKICAgICAgICB9CiAgICB9CiAgICAvKiBlbHNlIChsaWZldGltZSA8IDApID0+IG5ldmVyIGV4cGlyZXMgKi8KCiAgICByZXR1cm4gT0s7Cn0KCi8qIFRoZSBhY3R1YWwgTUQ1IGNvZGUuLi4gd2hlZSAqLwoKLyogUkZDLTIwNjkgKi8Kc3RhdGljIGNvbnN0IGNoYXIgKm9sZF9kaWdlc3QoY29uc3QgcmVxdWVzdF9yZWMgKnIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGRpZ2VzdF9oZWFkZXJfcmVjICpyZXNwLCBjb25zdCBjaGFyICpoYTEpCnsKICAgIGNvbnN0IGNoYXIgKmhhMjsKCiAgICBoYTIgPSBhcF9tZDUoci0+cG9vbCwgKHVuc2lnbmVkIGNoYXIgKilhcHJfcHN0cmNhdChyLT5wb29sLCByZXNwLT5tZXRob2QsICI6IiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlc3AtPnVyaSwgTlVMTCkpOwogICAgcmV0dXJuIGFwX21kNShyLT5wb29sLAogICAgICAgICAgICAgICAgICAodW5zaWduZWQgY2hhciAqKWFwcl9wc3RyY2F0KHItPnBvb2wsIGhhMSwgIjoiLCByZXNwLT5ub25jZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICI6IiwgaGEyLCBOVUxMKSk7Cn0KCi8qIFJGQy0yNjE3ICovCnN0YXRpYyBjb25zdCBjaGFyICpuZXdfZGlnZXN0KGNvbnN0IHJlcXVlc3RfcmVjICpyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkaWdlc3RfaGVhZGVyX3JlYyAqcmVzcCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgZGlnZXN0X2NvbmZpZ19yZWMgKmNvbmYpCnsKICAgIGNvbnN0IGNoYXIgKmhhMSwgKmhhMiwgKmEyOwoKICAgIGhhMSA9IGNvbmYtPmhhMTsKCiAgICBhMiA9IGFwcl9wc3RyY2F0KHItPnBvb2wsIHJlc3AtPm1ldGhvZCwgIjoiLCByZXNwLT51cmksIE5VTEwpOwogICAgaGEyID0gYXBfbWQ1KHItPnBvb2wsIChjb25zdCB1bnNpZ25lZCBjaGFyICopYTIpOwoKICAgIHJldHVybiBhcF9tZDUoci0+cG9vbCwKICAgICAgICAgICAgICAgICAgKHVuc2lnbmVkIGNoYXIgKilhcHJfcHN0cmNhdChyLT5wb29sLCBoYTEsICI6IiwgcmVzcC0+bm9uY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIjoiLCByZXNwLT5ub25jZV9jb3VudCwgIjoiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlc3AtPmNub25jZSwgIjoiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlc3AtPm1lc3NhZ2VfcW9wLCAiOiIsIGhhMiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBOVUxMKSk7Cn0KCgpzdGF0aWMgdm9pZCBjb3B5X3VyaV9jb21wb25lbnRzKGFwcl91cmlfdCAqZHN0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFwcl91cmlfdCAqc3JjLCByZXF1ZXN0X3JlYyAqcikgewogICAgaWYgKHNyYy0+c2NoZW1lICYmIHNyYy0+c2NoZW1lWzBdICE9ICdcMCcpIHsKICAgICAgICBkc3QtPnNjaGVtZSA9IHNyYy0+c2NoZW1lOwogICAgfQogICAgZWxzZSB7CiAgICAgICAgZHN0LT5zY2hlbWUgPSAoY2hhciAqKSAiaHR0cCI7CiAgICB9CgogICAgaWYgKHNyYy0+aG9zdG5hbWUgJiYgc3JjLT5ob3N0bmFtZVswXSAhPSAnXDAnKSB7CiAgICAgICAgZHN0LT5ob3N0bmFtZSA9IGFwcl9wc3RyZHVwKHItPnBvb2wsIHNyYy0+aG9zdG5hbWUpOwogICAgICAgIGFwX3VuZXNjYXBlX3VybChkc3QtPmhvc3RuYW1lKTsKICAgIH0KICAgIGVsc2UgewogICAgICAgIGRzdC0+aG9zdG5hbWUgPSAoY2hhciAqKSBhcF9nZXRfc2VydmVyX25hbWUocik7CiAgICB9CgogICAgaWYgKHNyYy0+cG9ydF9zdHIgJiYgc3JjLT5wb3J0X3N0clswXSAhPSAnXDAnKSB7CiAgICAgICAgZHN0LT5wb3J0ID0gc3JjLT5wb3J0OwogICAgfQogICAgZWxzZSB7CiAgICAgICAgZHN0LT5wb3J0ID0gYXBfZ2V0X3NlcnZlcl9wb3J0KHIpOwogICAgfQoKICAgIGlmIChzcmMtPnBhdGggJiYgc3JjLT5wYXRoWzBdICE9ICdcMCcpIHsKICAgICAgICBkc3QtPnBhdGggPSBhcHJfcHN0cmR1cChyLT5wb29sLCBzcmMtPnBhdGgpOwogICAgICAgIGFwX3VuZXNjYXBlX3VybChkc3QtPnBhdGgpOwogICAgfQogICAgZWxzZSB7CiAgICAgICAgZHN0LT5wYXRoID0gc3JjLT5wYXRoOwogICAgfQoKICAgIGlmIChzcmMtPnF1ZXJ5ICYmIHNyYy0+cXVlcnlbMF0gIT0gJ1wwJykgewogICAgICAgIGRzdC0+cXVlcnkgPSBhcHJfcHN0cmR1cChyLT5wb29sLCBzcmMtPnF1ZXJ5KTsKICAgICAgICBhcF91bmVzY2FwZV91cmwoZHN0LT5xdWVyeSk7CiAgICB9CiAgICBlbHNlIHsKICAgICAgICBkc3QtPnF1ZXJ5ID0gc3JjLT5xdWVyeTsKICAgIH0KCiAgICBkc3QtPmhvc3RpbmZvID0gc3JjLT5ob3N0aW5mbzsKfQoKLyogVGhlc2UgZnVuY3Rpb25zIHJldHVybiAwIGlmIGNsaWVudCBpcyBPSywgYW5kIHByb3BlciBlcnJvciBzdGF0dXMKICogaWYgbm90Li4uIGVpdGhlciBIVFRQX1VOQVVUSE9SSVpFRCwgaWYgd2UgbWFkZSBhIGNoZWNrLCBhbmQgaXQgZmFpbGVkLCBvcgogKiBIVFRQX0lOVEVSTkFMX1NFUlZFUl9FUlJPUiwgaWYgdGhpbmdzIGFyZSBzbyB0b3RhbGx5IGNvbmZ1c2VkIHRoYXQgd2UKICogY291bGRuJ3QgZmlndXJlIG91dCBob3cgdG8gdGVsbCBpZiB0aGUgY2xpZW50IGlzIGF1dGhvcml6ZWQgb3Igbm90LgogKgogKiBJZiB0aGV5IHJldHVybiBERUNMSU5FRCwgYW5kIGFsbCBvdGhlciBtb2R1bGVzIGFsc28gZGVjbGluZSwgdGhhdCdzCiAqIHRyZWF0ZWQgYnkgdGhlIHNlcnZlciBjb3JlIGFzIGEgY29uZmlndXJhdGlvbiBlcnJvciwgbG9nZ2VkIGFuZAogKiByZXBvcnRlZCBhcyBzdWNoLgogKi8KCi8qIERldGVybWluZSB1c2VyIElELCBhbmQgY2hlY2sgaWYgdGhlIGF0dHJpYnV0ZXMgYXJlIGNvcnJlY3QsIGlmIGl0CiAqIHJlYWxseSBpcyB0aGF0IHVzZXIsIGlmIHRoZSBub25jZSBpcyBjb3JyZWN0LCBldGMuCiAqLwoKc3RhdGljIGludCBhdXRoZW50aWNhdGVfZGlnZXN0X3VzZXIocmVxdWVzdF9yZWMgKnIpCnsKICAgIGRpZ2VzdF9jb25maWdfcmVjICpjb25mOwogICAgZGlnZXN0X2hlYWRlcl9yZWMgKnJlc3A7CiAgICByZXF1ZXN0X3JlYyAgICAgICAqbWFpbnJlcTsKICAgIGNvbnN0IGNoYXIgICAgICAgICp0OwogICAgaW50ICAgICAgICAgICAgICAgIHJlczsKICAgIGF1dGhuX3N0YXR1cyAgICAgICByZXR1cm5fY29kZTsKICAgIGNvbnN0IGNoYXIgKnJlYWxtOwoKICAgIC8qIGRvIHdlIHJlcXVpcmUgRGlnZXN0IGF1dGggZm9yIHRoaXMgVVJJPyAqLwoKICAgIGlmICghKHQgPSBhcF9hdXRoX3R5cGUocikpIHx8IGFwX2NzdHJfY2FzZWNtcCh0LCAiRGlnZXN0IikpIHsKICAgICAgICByZXR1cm4gREVDTElORUQ7CiAgICB9CgogICAgaWYgKCFhcF9hdXRoX25hbWUocikpIHsKICAgICAgICBhcF9sb2dfcmVycm9yKEFQTE9HX01BUkssIEFQTE9HX0VSUiwgMCwgciwgQVBMT0dOTygwMTc4MCkKICAgICAgICAgICAgICAgICAgICAgICJuZWVkIEF1dGhOYW1lOiAlcyIsIHItPnVyaSk7CiAgICAgICAgcmV0dXJuIEhUVFBfSU5URVJOQUxfU0VSVkVSX0VSUk9SOwogICAgfQoKCiAgICAvKiBnZXQgdGhlIGNsaWVudCByZXNwb25zZSBhbmQgbWFyayAqLwoKICAgIG1haW5yZXEgPSByOwogICAgd2hpbGUgKG1haW5yZXEtPm1haW4gIT0gTlVMTCkgewogICAgICAgIG1haW5yZXEgPSBtYWlucmVxLT5tYWluOwogICAgfQogICAgd2hpbGUgKG1haW5yZXEtPnByZXYgIT0gTlVMTCkgewogICAgICAgIG1haW5yZXEgPSBtYWlucmVxLT5wcmV2OwogICAgfQogICAgcmVzcCA9IChkaWdlc3RfaGVhZGVyX3JlYyAqKSBhcF9nZXRfbW9kdWxlX2NvbmZpZyhtYWlucmVxLT5yZXF1ZXN0X2NvbmZpZywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJmF1dGhfZGlnZXN0X21vZHVsZSk7CiAgICByZXNwLT5uZWVkZWRfYXV0aCA9IDE7CgogICAgcmVhbG0gPSBhcF9hdXRoX25hbWUocik7CgogICAgLyogZ2V0IG91ciBjb25mICovCgogICAgY29uZiA9IChkaWdlc3RfY29uZmlnX3JlYyAqKSBhcF9nZXRfbW9kdWxlX2NvbmZpZyhyLT5wZXJfZGlyX2NvbmZpZywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJmF1dGhfZGlnZXN0X21vZHVsZSk7CgoKICAgIC8qIGNoZWNrIGZvciBleGlzdGVuY2UgYW5kIHN5bnRheCBvZiBBdXRoIGhlYWRlciAqLwoKICAgIGlmIChyZXNwLT5hdXRoX2hkcl9zdHMgIT0gVkFMSUQpIHsKICAgICAgICBpZiAocmVzcC0+YXV0aF9oZHJfc3RzID09IE5PVF9ESUdFU1QpIHsKICAgICAgICAgICAgYXBfbG9nX3JlcnJvcihBUExPR19NQVJLLCBBUExPR19FUlIsIDAsIHIsIEFQTE9HTk8oMDE3ODEpCiAgICAgICAgICAgICAgICAgICAgICAgICAgImNsaWVudCB1c2VkIHdyb25nIGF1dGhlbnRpY2F0aW9uIHNjaGVtZSBgJXMnOiAlcyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzcC0+c2NoZW1lLCByLT51cmkpOwogICAgICAgIH0KICAgICAgICBlbHNlIGlmIChyZXNwLT5hdXRoX2hkcl9zdHMgPT0gSU5WQUxJRCkgewogICAgICAgICAgICBhcF9sb2dfcmVycm9yKEFQTE9HX01BUkssIEFQTE9HX0VSUiwgMCwgciwgQVBMT0dOTygwMTc4MikKICAgICAgICAgICAgICAgICAgICAgICAgICAibWlzc2luZyB1c2VyLCByZWFsbSwgbm9uY2UsIHVyaSwgZGlnZXN0LCAiCiAgICAgICAgICAgICAgICAgICAgICAgICAgImNub25jZSwgb3Igbm9uY2VfY291bnQgaW4gYXV0aG9yaXphdGlvbiBoZWFkZXI6ICVzIiwKICAgICAgICAgICAgICAgICAgICAgICAgICByLT51cmkpOwogICAgICAgIH0KICAgICAgICAvKiBlbHNlIChyZXNwLT5hdXRoX2hkcl9zdHMgPT0gTk9fSEVBREVSKSAqLwogICAgICAgIG5vdGVfZGlnZXN0X2F1dGhfZmFpbHVyZShyLCBjb25mLCByZXNwLCAwKTsKICAgICAgICByZXR1cm4gSFRUUF9VTkFVVEhPUklaRUQ7CiAgICB9CgogICAgci0+dXNlciAgICAgICAgID0gKGNoYXIgKikgcmVzcC0+dXNlcm5hbWU7CiAgICByLT5hcF9hdXRoX3R5cGUgPSAoY2hhciAqKSAiRGlnZXN0IjsKCiAgICAvKiBjaGVjayB0aGUgYXV0aCBhdHRyaWJ1dGVzICovCgogICAgaWYgKHN0cmNtcChyZXNwLT51cmksIHJlc3AtPnJhd19yZXF1ZXN0X3VyaSkpIHsKICAgICAgICAvKiBIbW0sIHRoZSBzaW1wbGUgbWF0Y2ggZGlkbid0IHdvcmsgKHByb2JhYmx5IGEgcHJveHkgbW9kaWZpZWQgdGhlCiAgICAgICAgICogcmVxdWVzdC11cmkpLCBzbyBsZXRzIGRvIGEgbW9yZSBzb3BoaXN0aWNhdGVkIG1hdGNoCiAgICAgICAgICovCiAgICAgICAgYXByX3VyaV90IHJfdXJpLCBkX3VyaTsKCiAgICAgICAgY29weV91cmlfY29tcG9uZW50cygmcl91cmksIHJlc3AtPnBzZF9yZXF1ZXN0X3VyaSwgcik7CiAgICAgICAgaWYgKGFwcl91cmlfcGFyc2Uoci0+cG9vbCwgcmVzcC0+dXJpLCAmZF91cmkpICE9IEFQUl9TVUNDRVNTKSB7CiAgICAgICAgICAgIGFwX2xvZ19yZXJyb3IoQVBMT0dfTUFSSywgQVBMT0dfRVJSLCAwLCByLCBBUExPR05PKDAxNzgzKQogICAgICAgICAgICAgICAgICAgICAgICAgICJpbnZhbGlkIHVyaSA8JXM+IGluIEF1dGhvcml6YXRpb24gaGVhZGVyIiwKICAgICAgICAgICAgICAgICAgICAgICAgICByZXNwLT51cmkpOwogICAgICAgICAgICByZXR1cm4gSFRUUF9CQURfUkVRVUVTVDsKICAgICAgICB9CgogICAgICAgIGlmIChkX3VyaS5ob3N0bmFtZSkgewogICAgICAgICAgICBhcF91bmVzY2FwZV91cmwoZF91cmkuaG9zdG5hbWUpOwogICAgICAgIH0KICAgICAgICBpZiAoZF91cmkucGF0aCkgewogICAgICAgICAgICBhcF91bmVzY2FwZV91cmwoZF91cmkucGF0aCk7CiAgICAgICAgfQoKICAgICAgICBpZiAoZF91cmkucXVlcnkpIHsKICAgICAgICAgICAgYXBfdW5lc2NhcGVfdXJsKGRfdXJpLnF1ZXJ5KTsKICAgICAgICB9CgogICAgICAgIGlmIChyLT5tZXRob2RfbnVtYmVyID09IE1fQ09OTkVDVCkgewogICAgICAgICAgICBpZiAoIXJfdXJpLmhvc3RpbmZvIHx8IHN0cmNtcChyZXNwLT51cmksIHJfdXJpLmhvc3RpbmZvKSkgewogICAgICAgICAgICAgICAgYXBfbG9nX3JlcnJvcihBUExPR19NQVJLLCBBUExPR19FUlIsIDAsIHIsIEFQTE9HTk8oMDE3ODUpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJ1cmkgbWlzbWF0Y2ggLSA8JXM+IGRvZXMgbm90IG1hdGNoICIKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgInJlcXVlc3QtdXJpIDwlcz4iLCByZXNwLT51cmksIHJfdXJpLmhvc3RpbmZvKTsKICAgICAgICAgICAgICAgIHJldHVybiBIVFRQX0JBRF9SRVFVRVNUOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGVsc2UgaWYgKAogICAgICAgICAgICAvKiBjaGVjayBob3N0bmFtZSBtYXRjaGVzLCBpZiBwcmVzZW50ICovCiAgICAgICAgICAgIChkX3VyaS5ob3N0bmFtZSAmJiBkX3VyaS5ob3N0bmFtZVswXSAhPSAnXDAnCiAgICAgICAgICAgICAgJiYgc3RyY2FzZWNtcChkX3VyaS5ob3N0bmFtZSwgcl91cmkuaG9zdG5hbWUpKQogICAgICAgICAgICAvKiBjaGVjayBwb3J0IG1hdGNoZXMsIGlmIHByZXNlbnQgKi8KICAgICAgICAgICAgfHwgKGRfdXJpLnBvcnRfc3RyICYmIGRfdXJpLnBvcnQgIT0gcl91cmkucG9ydCkKICAgICAgICAgICAgLyogY2hlY2sgdGhhdCBzZXJ2ZXItcG9ydCBpcyBkZWZhdWx0IHBvcnQgaWYgbm8gcG9ydCBwcmVzZW50ICovCiAgICAgICAgICAgIHx8IChkX3VyaS5ob3N0bmFtZSAmJiBkX3VyaS5ob3N0bmFtZVswXSAhPSAnXDAnCiAgICAgICAgICAgICAgICAmJiAhZF91cmkucG9ydF9zdHIgJiYgcl91cmkucG9ydCAhPSBhcF9kZWZhdWx0X3BvcnQocikpCiAgICAgICAgICAgIC8qIGNoZWNrIHRoYXQgcGF0aCBtYXRjaGVzICovCiAgICAgICAgICAgIHx8IChkX3VyaS5wYXRoICE9IHJfdXJpLnBhdGgKICAgICAgICAgICAgICAgIC8qIGVpdGhlciBleGFjdCBtYXRjaCAqLwogICAgICAgICAgICAgICAgJiYgKCFkX3VyaS5wYXRoIHx8ICFyX3VyaS5wYXRoCiAgICAgICAgICAgICAgICAgICAgfHwgc3RyY21wKGRfdXJpLnBhdGgsIHJfdXJpLnBhdGgpKQogICAgICAgICAgICAgICAgLyogb3IgJyonIG1hdGNoZXMgZW1wdHkgcGF0aCBpbiBzY2hlbWU6Ly9ob3N0ICovCiAgICAgICAgICAgICAgICAmJiAhKGRfdXJpLnBhdGggJiYgIXJfdXJpLnBhdGggJiYgcmVzcC0+cHNkX3JlcXVlc3RfdXJpLT5ob3N0bmFtZQogICAgICAgICAgICAgICAgICAgICYmIGRfdXJpLnBhdGhbMF0gPT0gJyonICYmIGRfdXJpLnBhdGhbMV0gPT0gJ1wwJykpCiAgICAgICAgICAgIC8qIGNoZWNrIHRoYXQgcXVlcnkgbWF0Y2hlcyAqLwogICAgICAgICAgICB8fCAoZF91cmkucXVlcnkgIT0gcl91cmkucXVlcnkKICAgICAgICAgICAgICAgICYmICghZF91cmkucXVlcnkgfHwgIXJfdXJpLnF1ZXJ5CiAgICAgICAgICAgICAgICAgICAgfHwgc3RyY21wKGRfdXJpLnF1ZXJ5LCByX3VyaS5xdWVyeSkpKQogICAgICAgICAgICApIHsKICAgICAgICAgICAgYXBfbG9nX3JlcnJvcihBUExPR19NQVJLLCBBUExPR19FUlIsIDAsIHIsIEFQTE9HTk8oMDE3ODYpCiAgICAgICAgICAgICAgICAgICAgICAgICAgInVyaSBtaXNtYXRjaCAtIDwlcz4gZG9lcyBub3QgbWF0Y2ggIgogICAgICAgICAgICAgICAgICAgICAgICAgICJyZXF1ZXN0LXVyaSA8JXM+IiwgcmVzcC0+dXJpLCByZXNwLT5yYXdfcmVxdWVzdF91cmkpOwogICAgICAgICAgICByZXR1cm4gSFRUUF9CQURfUkVRVUVTVDsKICAgICAgICB9CiAgICB9CgogICAgaWYgKHJlc3AtPm9wYXF1ZSAmJiByZXNwLT5vcGFxdWVfbnVtID09IDApIHsKICAgICAgICBhcF9sb2dfcmVycm9yKEFQTE9HX01BUkssIEFQTE9HX0VSUiwgMCwgciwgQVBMT0dOTygwMTc4NykKICAgICAgICAgICAgICAgICAgICAgICJyZWNlaXZlZCBpbnZhbGlkIG9wYXF1ZSAtIGdvdCBgJXMnIiwKICAgICAgICAgICAgICAgICAgICAgIHJlc3AtPm9wYXF1ZSk7CiAgICAgICAgbm90ZV9kaWdlc3RfYXV0aF9mYWlsdXJlKHIsIGNvbmYsIHJlc3AsIDApOwogICAgICAgIHJldHVybiBIVFRQX1VOQVVUSE9SSVpFRDsKICAgIH0KIAogICAgCgogICAgaWYgKCFyZWFsbSkgewogICAgICAgIGFwX2xvZ19yZXJyb3IoQVBMT0dfTUFSSywgQVBMT0dfRVJSLCAwLCByLCBBUExPR05PKDAyNTMzKQogICAgICAgICAgICAgICAgICAgICAgInJlYWxtIG1pc21hdGNoIC0gZ290IGAlcycgYnV0IG5vIHJlYWxtIHNwZWNpZmllZCIsCiAgICAgICAgICAgICAgICAgICAgICByZXNwLT5yZWFsbSk7CiAgICAgICAgbm90ZV9kaWdlc3RfYXV0aF9mYWlsdXJlKHIsIGNvbmYsIHJlc3AsIDApOwogICAgICAgIHJldHVybiBIVFRQX1VOQVVUSE9SSVpFRDsKICAgIH0KCiAgICBpZiAoIXJlc3AtPnJlYWxtIHx8IHN0cmNtcChyZXNwLT5yZWFsbSwgcmVhbG0pKSB7CiAgICAgICAgYXBfbG9nX3JlcnJvcihBUExPR19NQVJLLCBBUExPR19FUlIsIDAsIHIsIEFQTE9HTk8oMDE3ODgpCiAgICAgICAgICAgICAgICAgICAgICAicmVhbG0gbWlzbWF0Y2ggLSBnb3QgYCVzJyBidXQgZXhwZWN0ZWQgYCVzJyIsCiAgICAgICAgICAgICAgICAgICAgICByZXNwLT5yZWFsbSwgcmVhbG0pOwogICAgICAgIG5vdGVfZGlnZXN0X2F1dGhfZmFpbHVyZShyLCBjb25mLCByZXNwLCAwKTsKICAgICAgICByZXR1cm4gSFRUUF9VTkFVVEhPUklaRUQ7CiAgICB9CgogICAgaWYgKHJlc3AtPmFsZ29yaXRobSAhPSBOVUxMCiAgICAgICAgJiYgYXBfY3N0cl9jYXNlY21wKHJlc3AtPmFsZ29yaXRobSwgIk1ENSIpKSB7CiAgICAgICAgYXBfbG9nX3JlcnJvcihBUExPR19NQVJLLCBBUExPR19FUlIsIDAsIHIsIEFQTE9HTk8oMDE3ODkpCiAgICAgICAgICAgICAgICAgICAgICAidW5rbm93biBhbGdvcml0aG0gYCVzJyByZWNlaXZlZDogJXMiLAogICAgICAgICAgICAgICAgICAgICAgcmVzcC0+YWxnb3JpdGhtLCByLT51cmkpOwogICAgICAgIG5vdGVfZGlnZXN0X2F1dGhfZmFpbHVyZShyLCBjb25mLCByZXNwLCAwKTsKICAgICAgICByZXR1cm4gSFRUUF9VTkFVVEhPUklaRUQ7CiAgICB9CgogICAgcmV0dXJuX2NvZGUgPSBnZXRfaGFzaChyLCByLT51c2VyLCBjb25mKTsKCiAgICBpZiAocmV0dXJuX2NvZGUgPT0gQVVUSF9VU0VSX05PVF9GT1VORCkgewogICAgICAgIGFwX2xvZ19yZXJyb3IoQVBMT0dfTUFSSywgQVBMT0dfRVJSLCAwLCByLCBBUExPR05PKDAxNzkwKQogICAgICAgICAgICAgICAgICAgICAgInVzZXIgYCVzJyBpbiByZWFsbSBgJXMnIG5vdCBmb3VuZDogJXMiLAogICAgICAgICAgICAgICAgICAgICAgci0+dXNlciwgcmVhbG0sIHItPnVyaSk7CiAgICAgICAgbm90ZV9kaWdlc3RfYXV0aF9mYWlsdXJlKHIsIGNvbmYsIHJlc3AsIDApOwogICAgICAgIHJldHVybiBIVFRQX1VOQVVUSE9SSVpFRDsKICAgIH0KICAgIGVsc2UgaWYgKHJldHVybl9jb2RlID09IEFVVEhfVVNFUl9GT1VORCkgewogICAgICAgIC8qIHdlIGhhdmUgYSBwYXNzd29yZCwgc28gY29udGludWUgKi8KICAgIH0KICAgIGVsc2UgaWYgKHJldHVybl9jb2RlID09IEFVVEhfREVOSUVEKSB7CiAgICAgICAgLyogYXV0aGVudGljYXRpb24gZGVuaWVkIGluIHRoZSBwcm92aWRlciBiZWZvcmUgYXR0ZW1wdGluZyBhIG1hdGNoICovCiAgICAgICAgYXBfbG9nX3JlcnJvcihBUExPR19NQVJLLCBBUExPR19FUlIsIDAsIHIsIEFQTE9HTk8oMDE3OTEpCiAgICAgICAgICAgICAgICAgICAgICAidXNlciBgJXMnIGluIHJlYWxtIGAlcycgZGVuaWVkIGJ5IHByb3ZpZGVyOiAlcyIsCiAgICAgICAgICAgICAgICAgICAgICByLT51c2VyLCByZWFsbSwgci0+dXJpKTsKICAgICAgICBub3RlX2RpZ2VzdF9hdXRoX2ZhaWx1cmUociwgY29uZiwgcmVzcCwgMCk7CiAgICAgICAgcmV0dXJuIEhUVFBfVU5BVVRIT1JJWkVEOwogICAgfQogICAgZWxzZSBpZiAocmV0dXJuX2NvZGUgPT0gQVVUSF9IQU5ETEVEKSB7CiAgICAgICAgcmV0dXJuIHItPnN0YXR1czsKICAgIH0KICAgIGVsc2UgewogICAgICAgIC8qIEFVVEhfR0VORVJBTF9FUlJPUiAob3Igd29yc2UpCiAgICAgICAgICogV2UnbGwgYXNzdW1lIHRoYXQgdGhlIG1vZHVsZSBoYXMgYWxyZWFkeSBzYWlkIHdoYXQgaXRzIGVycm9yCiAgICAgICAgICogd2FzIGluIHRoZSBsb2dzLgogICAgICAgICAqLwogICAgICAgIHJldHVybiBIVFRQX0lOVEVSTkFMX1NFUlZFUl9FUlJPUjsKICAgIH0KCiAgICBpZiAocmVzcC0+bWVzc2FnZV9xb3AgPT0gTlVMTCkgewogICAgICAgIC8qIG9sZCAocmZjLTIwNjkpIHN0eWxlIGRpZ2VzdCAqLwogICAgICAgIGlmIChzdHJjbXAocmVzcC0+ZGlnZXN0LCBvbGRfZGlnZXN0KHIsIHJlc3AsIGNvbmYtPmhhMSkpKSB7CiAgICAgICAgICAgIGFwX2xvZ19yZXJyb3IoQVBMT0dfTUFSSywgQVBMT0dfRVJSLCAwLCByLCBBUExPR05PKDAxNzkyKQogICAgICAgICAgICAgICAgICAgICAgICAgICJ1c2VyICVzOiBwYXNzd29yZCBtaXNtYXRjaDogJXMiLCByLT51c2VyLAogICAgICAgICAgICAgICAgICAgICAgICAgIHItPnVyaSk7CiAgICAgICAgICAgIG5vdGVfZGlnZXN0X2F1dGhfZmFpbHVyZShyLCBjb25mLCByZXNwLCAwKTsKICAgICAgICAgICAgcmV0dXJuIEhUVFBfVU5BVVRIT1JJWkVEOwogICAgICAgIH0KICAgIH0KICAgIGVsc2UgewogICAgICAgIGNvbnN0IGNoYXIgKmV4cF9kaWdlc3Q7CiAgICAgICAgaW50IG1hdGNoID0gMCwgaWR4OwogICAgICAgIGNvbnN0IGNoYXIgKip0bXAgPSAoY29uc3QgY2hhciAqKikoY29uZi0+cW9wX2xpc3QtPmVsdHMpOwogICAgICAgIGZvciAoaWR4ID0gMDsgaWR4IDwgY29uZi0+cW9wX2xpc3QtPm5lbHRzOyBpZHgrKykgewogICAgICAgICAgICBpZiAoIWFwX2NzdHJfY2FzZWNtcCgqdG1wLCByZXNwLT5tZXNzYWdlX3FvcCkpIHsKICAgICAgICAgICAgICAgIG1hdGNoID0gMTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9CiAgICAgICAgICAgICsrdG1wOwogICAgICAgIH0KCiAgICAgICAgaWYgKCFtYXRjaAogICAgICAgICAgICAmJiAhKGFwcl9pc19lbXB0eV9hcnJheShjb25mLT5xb3BfbGlzdCkKICAgICAgICAgICAgICAgICAmJiAhYXBfY3N0cl9jYXNlY21wKHJlc3AtPm1lc3NhZ2VfcW9wLCAiYXV0aCIpKSkgewogICAgICAgICAgICBhcF9sb2dfcmVycm9yKEFQTE9HX01BUkssIEFQTE9HX0VSUiwgMCwgciwgQVBMT0dOTygwMTc5MykKICAgICAgICAgICAgICAgICAgICAgICAgICAiaW52YWxpZCBxb3AgYCVzJyByZWNlaXZlZDogJXMiLAogICAgICAgICAgICAgICAgICAgICAgICAgIHJlc3AtPm1lc3NhZ2VfcW9wLCByLT51cmkpOwogICAgICAgICAgICBub3RlX2RpZ2VzdF9hdXRoX2ZhaWx1cmUociwgY29uZiwgcmVzcCwgMCk7CiAgICAgICAgICAgIHJldHVybiBIVFRQX1VOQVVUSE9SSVpFRDsKICAgICAgICB9CgogICAgICAgIGV4cF9kaWdlc3QgPSBuZXdfZGlnZXN0KHIsIHJlc3AsIGNvbmYpOwogICAgICAgIGlmICghZXhwX2RpZ2VzdCkgewogICAgICAgICAgICAvKiB3ZSBmYWlsZWQgdG8gYWxsb2NhdGUgYSBjbGllbnQgc3RydWN0ICovCiAgICAgICAgICAgIHJldHVybiBIVFRQX0lOVEVSTkFMX1NFUlZFUl9FUlJPUjsKICAgICAgICB9CiAgICAgICAgaWYgKHN0cmNtcChyZXNwLT5kaWdlc3QsIGV4cF9kaWdlc3QpKSB7CiAgICAgICAgICAgIGFwX2xvZ19yZXJyb3IoQVBMT0dfTUFSSywgQVBMT0dfRVJSLCAwLCByLCBBUExPR05PKDAxNzk0KQogICAgICAgICAgICAgICAgICAgICAgICAgICJ1c2VyICVzOiBwYXNzd29yZCBtaXNtYXRjaDogJXMiLCByLT51c2VyLAogICAgICAgICAgICAgICAgICAgICAgICAgIHItPnVyaSk7CiAgICAgICAgICAgIG5vdGVfZGlnZXN0X2F1dGhfZmFpbHVyZShyLCBjb25mLCByZXNwLCAwKTsKICAgICAgICAgICAgcmV0dXJuIEhUVFBfVU5BVVRIT1JJWkVEOwogICAgICAgIH0KICAgIH0KCiAgICBpZiAoY2hlY2tfbmMociwgcmVzcCwgY29uZikgIT0gT0spIHsKICAgICAgICBub3RlX2RpZ2VzdF9hdXRoX2ZhaWx1cmUociwgY29uZiwgcmVzcCwgMCk7CiAgICAgICAgcmV0dXJuIEhUVFBfVU5BVVRIT1JJWkVEOwogICAgfQoKICAgIC8qIE5vdGU6IHRoaXMgY2hlY2sgaXMgZG9uZSBsYXN0IHNvIHRoYXQgYSAic3RhbGU9dHJ1ZSIgY2FuIGJlCiAgICAgICBnZW5lcmF0ZWQgaWYgdGhlIG5vbmNlIGlzIG9sZCAqLwogICAgaWYgKChyZXMgPSBjaGVja19ub25jZShyLCByZXNwLCBjb25mKSkpIHsKICAgICAgICByZXR1cm4gcmVzOwogICAgfQoKICAgIHJldHVybiBPSzsKfQoKLyoKICogQXV0aG9yaXphdGlvbi1JbmZvIGhlYWRlciBjb2RlCiAqLwoKc3RhdGljIGludCBhZGRfYXV0aF9pbmZvKHJlcXVlc3RfcmVjICpyKQp7CiAgICBjb25zdCBkaWdlc3RfY29uZmlnX3JlYyAqY29uZiA9CiAgICAgICAgICAgICAgICAoZGlnZXN0X2NvbmZpZ19yZWMgKikgYXBfZ2V0X21vZHVsZV9jb25maWcoci0+cGVyX2Rpcl9jb25maWcsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJmF1dGhfZGlnZXN0X21vZHVsZSk7CiAgICBkaWdlc3RfaGVhZGVyX3JlYyAqcmVzcCA9CiAgICAgICAgICAgICAgICAoZGlnZXN0X2hlYWRlcl9yZWMgKikgYXBfZ2V0X21vZHVsZV9jb25maWcoci0+cmVxdWVzdF9jb25maWcsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJmF1dGhfZGlnZXN0X21vZHVsZSk7CiAgICBjb25zdCBjaGFyICphaSA9IE5VTEwsICpuZXh0bm9uY2UgPSAiIjsKCiAgICBpZiAocmVzcCA9PSBOVUxMIHx8ICFyZXNwLT5uZWVkZWRfYXV0aCB8fCBjb25mID09IE5VTEwpIHsKICAgICAgICByZXR1cm4gT0s7CiAgICB9CgogICAgLyogMjA2OS1zdHlsZSBlbnRpdHktZGlnZXN0IGlzIG5vdCBzdXBwb3J0ZWQgKGl0J3MgdG9vIGhhcmQsIGFuZAogICAgICogdGhlcmUgYXJlIG5vIGNsaWVudHMgd2hpY2ggc3VwcG9ydCAyMDY5IGJ1dCBub3QgMjYxNykuICovCgogICAgLyogc2V0dXAgbmV4dG5vbmNlCiAgICAgKi8KICAgIGlmIChjb25mLT5ub25jZV9saWZldGltZSA+IDApIHsKICAgICAgICAvKiBzZW5kIG5leHRub25jZSBpZiBjdXJyZW50IG5vbmNlIHdpbGwgZXhwaXJlIGluIGxlc3MgdGhhbiAzMCBzZWNzICovCiAgICAgICAgaWYgKChyLT5yZXF1ZXN0X3RpbWUgLSByZXNwLT5ub25jZV90aW1lKSA+IChjb25mLT5ub25jZV9saWZldGltZS1ORVhUTk9OQ0VfREVMVEEpKSB7CiAgICAgICAgICAgIG5leHRub25jZSA9IGFwcl9wc3RyY2F0KHItPnBvb2wsICIsIG5leHRub25jZT1cIiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZ2VuX25vbmNlKHItPnBvb2wsIHItPnJlcXVlc3RfdGltZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzcC0+b3BhcXVlLCByLT5zZXJ2ZXIsIGNvbmYsIGFwX2F1dGhfbmFtZShyKSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIlwiIiwgTlVMTCk7CiAgICAgICAgICAgIGlmIChyZXNwLT5jbGllbnQpCiAgICAgICAgICAgICAgICByZXNwLT5jbGllbnQtPm5vbmNlX2NvdW50ID0gMDsKICAgICAgICB9CiAgICB9CiAgICBlbHNlIGlmIChjb25mLT5ub25jZV9saWZldGltZSA9PSAwICYmIHJlc3AtPmNsaWVudCkgewogICAgICAgIGNvbnN0IGNoYXIgKm5vbmNlID0gZ2VuX25vbmNlKHItPnBvb2wsIDAsIHJlc3AtPm9wYXF1ZSwgci0+c2VydmVyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbmYsIGFwX2F1dGhfbmFtZShyKSk7CiAgICAgICAgbmV4dG5vbmNlID0gYXByX3BzdHJjYXQoci0+cG9vbCwgIiwgbmV4dG5vbmNlPVwiIiwgbm9uY2UsICJcIiIsIE5VTEwpOwogICAgICAgIG1lbWNweShyZXNwLT5jbGllbnQtPmxhc3Rfbm9uY2UsIG5vbmNlLCBOT05DRV9MRU4rMSk7CiAgICB9CiAgICAvKiBlbHNlIG5vbmNlIG5ldmVyIGV4cGlyZXMsIGhlbmNlIG5vIG5leHRub25jZSAqLwoKCiAgICAvKiBkbyByZmMtMjA2OSBkaWdlc3QKICAgICAqLwogICAgaWYgKCFhcHJfaXNfZW1wdHlfYXJyYXkoY29uZi0+cW9wX2xpc3QpICYmCiAgICAgICAgIWFwX2NzdHJfY2FzZWNtcCgqKGNvbnN0IGNoYXIgKiopKGNvbmYtPnFvcF9saXN0LT5lbHRzKSwgIm5vbmUiKQogICAgICAgICYmIHJlc3AtPm1lc3NhZ2VfcW9wID09IE5VTEwpIHsKICAgICAgICAvKiB1c2Ugb25seSBSRkMtMjA2OSBmb3JtYXQgKi8KICAgICAgICBhaSA9IG5leHRub25jZTsKICAgIH0KICAgIGVsc2UgewogICAgICAgIGNvbnN0IGNoYXIgKnJlc3BfZGlnLCAqaGExLCAqYTIsICpoYTI7CgogICAgICAgIC8qIGNhbGN1bGF0ZSByc3BhdXRoIGF0dHJpYnV0ZQogICAgICAgICAqLwogICAgICAgIGhhMSA9IGNvbmYtPmhhMTsKCiAgICAgICAgYTIgPSBhcHJfcHN0cmNhdChyLT5wb29sLCAiOiIsIHJlc3AtPnVyaSwgTlVMTCk7CiAgICAgICAgaGEyID0gYXBfbWQ1KHItPnBvb2wsIChjb25zdCB1bnNpZ25lZCBjaGFyICopYTIpOwoKICAgICAgICByZXNwX2RpZyA9IGFwX21kNShyLT5wb29sLAogICAgICAgICAgICAgICAgICAgICAgICAgICh1bnNpZ25lZCBjaGFyICopYXByX3BzdHJjYXQoci0+cG9vbCwgaGExLCAiOiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXNwLT5ub25jZSwgIjoiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzcC0+bm9uY2VfY291bnQsICI6IiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlc3AtPmNub25jZSwgIjoiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzcC0+bWVzc2FnZV9xb3AgPwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXNwLT5tZXNzYWdlX3FvcCA6ICIiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIjoiLCBoYTIsIE5VTEwpKTsKCiAgICAgICAgLyogYXNzZW1ibGUgQXV0aGVudGljYXRpb24tSW5mbyBoZWFkZXIKICAgICAgICAgKi8KICAgICAgICBhaSA9IGFwcl9wc3RyY2F0KHItPnBvb2wsCiAgICAgICAgICAgICAgICAgICAgICAgICAicnNwYXV0aD1cIiIsIHJlc3BfZGlnLCAiXCIiLAogICAgICAgICAgICAgICAgICAgICAgICAgbmV4dG5vbmNlLAogICAgICAgICAgICAgICAgICAgICAgICAgcmVzcC0+Y25vbmNlID8gIiwgY25vbmNlPVwiIiA6ICIiLAogICAgICAgICAgICAgICAgICAgICAgICAgcmVzcC0+Y25vbmNlCiAgICAgICAgICAgICAgICAgICAgICAgICAgID8gYXBfZXNjYXBlX3F1b3RlcyhyLT5wb29sLCByZXNwLT5jbm9uY2UpCiAgICAgICAgICAgICAgICAgICAgICAgICAgIDogIiIsCiAgICAgICAgICAgICAgICAgICAgICAgICByZXNwLT5jbm9uY2UgPyAiXCIiIDogIiIsCiAgICAgICAgICAgICAgICAgICAgICAgICByZXNwLT5ub25jZV9jb3VudCA/ICIsIG5jPSIgOiAiIiwKICAgICAgICAgICAgICAgICAgICAgICAgIHJlc3AtPm5vbmNlX2NvdW50ID8gcmVzcC0+bm9uY2VfY291bnQgOiAiIiwKICAgICAgICAgICAgICAgICAgICAgICAgIHJlc3AtPm1lc3NhZ2VfcW9wID8gIiwgcW9wPSIgOiAiIiwKICAgICAgICAgICAgICAgICAgICAgICAgIHJlc3AtPm1lc3NhZ2VfcW9wID8gcmVzcC0+bWVzc2FnZV9xb3AgOiAiIiwKICAgICAgICAgICAgICAgICAgICAgICAgIE5VTEwpOwogICAgfQoKICAgIGlmIChhaSAmJiBhaVswXSkgewogICAgICAgIGFwcl90YWJsZV9tZXJnZW4oci0+aGVhZGVyc19vdXQsCiAgICAgICAgICAgICAgICAgICAgICAgICAoUFJPWFlSRVFfUFJPWFkgPT0gci0+cHJveHlyZXEpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPyAiUHJveHktQXV0aGVudGljYXRpb24tSW5mbyIKICAgICAgICAgICAgICAgICAgICAgICAgICAgICA6ICJBdXRoZW50aWNhdGlvbi1JbmZvIiwKICAgICAgICAgICAgICAgICAgICAgICAgIGFpKTsKICAgIH0KCiAgICByZXR1cm4gT0s7Cn0KCnN0YXRpYyB2b2lkIHJlZ2lzdGVyX2hvb2tzKGFwcl9wb29sX3QgKnApCnsKICAgIHN0YXRpYyBjb25zdCBjaGFyICogY29uc3QgY2ZnUG9zdFtdPXsgImh0dHBfY29yZS5jIiwgTlVMTCB9OwogICAgc3RhdGljIGNvbnN0IGNoYXIgKiBjb25zdCBwYXJzZVByZVtdPXsgIm1vZF9wcm94eS5jIiwgTlVMTCB9OwoKICAgIGFwX2hvb2tfcHJlX2NvbmZpZyhwcmVfaW5pdCwgTlVMTCwgTlVMTCwgQVBSX0hPT0tfTUlERExFKTsKICAgIGFwX2hvb2tfcG9zdF9jb25maWcoaW5pdGlhbGl6ZV9tb2R1bGUsIE5VTEwsIGNmZ1Bvc3QsIEFQUl9IT09LX01JRERMRSk7CiAgICBhcF9ob29rX2NoaWxkX2luaXQoaW5pdGlhbGl6ZV9jaGlsZCwgTlVMTCwgTlVMTCwgQVBSX0hPT0tfTUlERExFKTsKICAgIGFwX2hvb2tfcG9zdF9yZWFkX3JlcXVlc3QocGFyc2VfaGRyX2FuZF91cGRhdGVfbmMsIHBhcnNlUHJlLCBOVUxMLCBBUFJfSE9PS19NSURETEUpOwogICAgYXBfaG9va19jaGVja19hdXRobihhdXRoZW50aWNhdGVfZGlnZXN0X3VzZXIsIE5VTEwsIE5VTEwsIEFQUl9IT09LX01JRERMRSwKICAgICAgICAgICAgICAgICAgICAgICAgQVBfQVVUSF9JTlRFUk5BTF9QRVJfQ09ORik7CgogICAgYXBfaG9va19maXh1cHMoYWRkX2F1dGhfaW5mbywgTlVMTCwgTlVMTCwgQVBSX0hPT0tfTUlERExFKTsKICAgIGFwX2hvb2tfbm90ZV9hdXRoX2ZhaWx1cmUoaG9va19ub3RlX2RpZ2VzdF9hdXRoX2ZhaWx1cmUsIE5VTEwsIE5VTEwsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEFQUl9IT09LX01JRERMRSk7Cgp9CgpBUF9ERUNMQVJFX01PRFVMRShhdXRoX2RpZ2VzdCkgPQp7CiAgICBTVEFOREFSRDIwX01PRFVMRV9TVFVGRiwKICAgIGNyZWF0ZV9kaWdlc3RfZGlyX2NvbmZpZywgICAvKiBkaXIgY29uZmlnIGNyZWF0ZXIgKi8KICAgIE5VTEwsICAgICAgICAgICAgICAgICAgICAgICAvKiBkaXIgbWVyZ2VyIC0tLSBkZWZhdWx0IGlzIHRvIG92ZXJyaWRlICovCiAgICBOVUxMLCAgICAgICAgICAgICAgICAgICAgICAgLyogc2VydmVyIGNvbmZpZyAqLwogICAgTlVMTCwgICAgICAgICAgICAgICAgICAgICAgIC8qIG1lcmdlIHNlcnZlciBjb25maWcgKi8KICAgIGRpZ2VzdF9jbWRzLCAgICAgICAgICAgICAgICAvKiBjb21tYW5kIHRhYmxlICovCiAgICByZWdpc3Rlcl9ob29rcyAgICAgICAgICAgICAgLyogcmVnaXN0ZXIgaG9va3MgKi8KfTsKCg==