Lyogdmk6IHNldCBzdz00IHRzPTQ6ICovCi8qCiAqIE1pbmkgbW91bnQgaW1wbGVtZW50YXRpb24gZm9yIGJ1c3lib3gKICoKICogQ29weXJpZ2h0IChDKSAxOTk1LCAxOTk2IGJ5IEJydWNlIFBlcmVucyA8YnJ1Y2VAcGl4YXIuY29tPi4KICogQ29weXJpZ2h0IChDKSAxOTk5LTIwMDQgYnkgRXJpayBBbmRlcnNlbiA8YW5kZXJzZW5AY29kZXBvZXQub3JnPgogKiBDb3B5cmlnaHQgKEMpIDIwMDUtMjAwNiBieSBSb2IgTGFuZGxleSA8cm9iQGxhbmRsZXkubmV0PgogKgogKiBMaWNlbnNlZCB1bmRlciBHUEx2MiBvciBsYXRlciwgc2VlIGZpbGUgTElDRU5TRSBpbiB0aGlzIHRhcmJhbGwgZm9yIGRldGFpbHMuCiAqLwoKLyogRGVzaWduIG5vdGVzOiBUaGVyZSBpcyBubyBzcGVjIGZvciBtb3VudC4gIFJlbWluZCBtZSB0byB3cml0ZSBvbmUuCgogICBtb3VudF9tYWluKCkgY2FsbHMgc2luZ2xlbW91bnQoKSB3aGljaCBjYWxscyBtb3VudF9pdF9ub3coKS4KCiAgIG1vdW50X21haW4oKSBjYW4gbG9vcCB0aHJvdWdoIC9ldGMvZnN0YWIgZm9yIG1vdW50IC1hCiAgIHNpbmdsZW1vdW50KCkgY2FuIGxvb3AgdGhyb3VnaCAvZXRjL2ZpbGVzeXN0ZW1zIGZvciBmc3R5cGUgZGV0ZWN0aW9uLgogICBtb3VudF9pdF9ub3coKSBkb2VzIHRoZSBhY3R1YWwgbW91bnQuCiovCgojaW5jbHVkZSA8bW50ZW50Lmg+CiNpbmNsdWRlICJsaWJiYi5oIgoKLyogTmVlZGVkIGZvciBuZnMgc3VwcG9ydCBvbmx5Li4uICovCiNpbmNsdWRlIDxzeXNsb2cuaD4KI2luY2x1ZGUgPHN5cy91dHNuYW1lLmg+CiN1bmRlZiBUUlVFCiN1bmRlZiBGQUxTRQojaW5jbHVkZSA8cnBjL3JwYy5oPgojaW5jbHVkZSA8cnBjL3BtYXBfcHJvdC5oPgojaW5jbHVkZSA8cnBjL3BtYXBfY2xudC5oPgoKI2lmbmRlZiBNU19TSUxFTlQKI2RlZmluZSBNU19TSUxFTlQJKDEgPDwgMTUpCiNlbmRpZgoKI2lmIGRlZmluZWQoX19kaWV0bGliY19fKQovKiAxNi4xMi4yMDA2LCBTYW1wbyBLZWxsb21ha2kgKHNhbXBvQGlraS5maSkKICogZGlldGxpYmMtMC4zMCBkb2VzIG5vdCBoYXZlIGltcGxlbWVudGF0aW9uIG9mIGdldG1udGVudF9yKCkgKi8Kc3RydWN0IG1udGVudCAqZ2V0bW50ZW50X3IoRklMRSogc3RyZWFtLCBzdHJ1Y3QgbW50ZW50KiByZXN1bHQsIGNoYXIqIGJ1ZmZlciwgaW50IGJ1ZnNpemUpCnsKCXN0cnVjdCBtbnRlbnQqIG1lbnQgPSBnZXRtbnRlbnQoc3RyZWFtKTsKCW1lbWNweShyZXN1bHQsIG1lbnQsIHNpemVvZihzdHJ1Y3QgbW50ZW50KSk7CglyZXR1cm4gcmVzdWx0Owp9CiNlbmRpZgoKI2RlZmluZSBnZXRtbnRlbnRfYnVmIGJiX2NvbW1vbl9idWZzaXoxCgoKLy8gTm90IHJlYWwgZmxhZ3MsIGJ1dCB3ZSB3YW50IHRvIGJlIGFibGUgdG8gY2hlY2sgZm9yIHRoaXMuCmVudW0gewoJTU9VTlRfVVNFUlMgID0gKDE8PDI4KSpFTkFCTEVfREVTS1RPUCwKCU1PVU5UX05PQVVUTyA9ICgxPDwyOSksCglNT1VOVF9TV0FQICAgPSAoMTw8MzApLAp9OwovLyBUT0RPOiBtb3JlICJ1c2VyIiBmbGFnIGNvbXBhdGliaWxpdHkuCi8vICJ1c2VyIiBvcHRpb24gKGZyb20gbW91bnQgbWFucGFnZSk6Ci8vIE9ubHkgdGhlIHVzZXIgdGhhdCBtb3VudGVkIGEgZmlsZXN5c3RlbSBjYW4gdW5tb3VudCBpdCBhZ2Fpbi4KLy8gSWYgYW55IHVzZXIgc2hvdWxkIGJlIGFibGUgdG8gdW5tb3VudCwgdGhlbiB1c2UgdXNlcnMgaW5zdGVhZCBvZiB1c2VyCi8vIGluIHRoZSBmc3RhYiBsaW5lLiAgVGhlIG93bmVyIG9wdGlvbiBpcyBzaW1pbGFyIHRvIHRoZSB1c2VyIG9wdGlvbiwKLy8gd2l0aCB0aGUgcmVzdHJpY3Rpb24gdGhhdCB0aGUgdXNlciBtdXN0IGJlIHRoZSBvd25lciBvZiB0aGUgc3BlY2lhbCBmaWxlLgovLyBUaGlzIG1heSBiZSB1c2VmdWwgZS5nLiBmb3IgL2Rldi9mZCBpZiBhIGxvZ2luIHNjcmlwdCBtYWtlcwovLyB0aGUgY29uc29sZSB1c2VyIG93bmVyIG9mIHRoaXMgZGV2aWNlLgoKLyogU3RhbmRhcmQgbW91bnQgb3B0aW9ucyAoZnJvbSAtbyBvcHRpb25zIG9yIC0tb3B0aW9ucyksIHdpdGggY29ycmVzcG9uZGluZwogKiBmbGFncyAqLwoKc3RydWN0IHsKCWNvbnN0IGNoYXIgKm5hbWU7Cglsb25nIGZsYWdzOwp9IHN0YXRpYyBtb3VudF9vcHRpb25zW10gPSB7CgkvLyBNU19GTEFHUyBzZXQgYSBiaXQuICB+TVNfRkxBR1MgZGlzYWJsZSB0aGF0IGJpdC4gIDAgZmxhZ3MgYXJlIE5PUHMuCgoJVVNFX0ZFQVRVUkVfTU9VTlRfTE9PUCgKCQl7Imxvb3AiLCAwfSwKCSkKCglVU0VfRkVBVFVSRV9NT1VOVF9GU1RBQigKCQl7ImRlZmF1bHRzIiwgMH0sCgkJLyogeyJxdWlldCIsIDB9LCAtIGRvIG5vdCBmaWx0ZXIgb3V0LCB2ZmF0IHdhbnRzIHRvIHNlZSBpdCAqLwoJCXsibm9hdXRvIiwgTU9VTlRfTk9BVVRPfSwKCQl7InN3IiwgTU9VTlRfU1dBUH0sCgkJeyJzd2FwIiwgTU9VTlRfU1dBUH0sCgkJVVNFX0RFU0tUT1AoeyJ1c2VyIiwgIE1PVU5UX1VTRVJTfSwpCgkJVVNFX0RFU0tUT1AoeyJ1c2VycyIsIE1PVU5UX1VTRVJTfSwpCgkpCgoJVVNFX0ZFQVRVUkVfTU9VTlRfRkxBR1MoCgkJLy8gdmZzIGZsYWdzCgkJeyJub3N1aWQiLCBNU19OT1NVSUR9LAoJCXsic3VpZCIsIH5NU19OT1NVSUR9LAoJCXsiZGV2Iiwgfk1TX05PREVWfSwKCQl7Im5vZGV2IiwgTVNfTk9ERVZ9LAoJCXsiZXhlYyIsIH5NU19OT0VYRUN9LAoJCXsibm9leGVjIiwgTVNfTk9FWEVDfSwKCQl7InN5bmMiLCBNU19TWU5DSFJPTk9VU30sCgkJeyJhc3luYyIsIH5NU19TWU5DSFJPTk9VU30sCgkJeyJhdGltZSIsIH5NU19OT0FUSU1FfSwKCQl7Im5vYXRpbWUiLCBNU19OT0FUSU1FfSwKCQl7ImRpcmF0aW1lIiwgfk1TX05PRElSQVRJTUV9LAoJCXsibm9kaXJhdGltZSIsIE1TX05PRElSQVRJTUV9LAoJCXsibG91ZCIsIH5NU19TSUxFTlR9LAoKCQkvLyBhY3Rpb24gZmxhZ3MKCgkJeyJiaW5kIiwgTVNfQklORH0sCgkJeyJtb3ZlIiwgTVNfTU9WRX0sCgkJeyJzaGFyZWQiLCBNU19TSEFSRUR9LAoJCXsic2xhdmUiLCBNU19TTEFWRX0sCgkJeyJwcml2YXRlIiwgTVNfUFJJVkFURX0sCgkJeyJ1bmJpbmRhYmxlIiwgTVNfVU5CSU5EQUJMRX0sCgkJeyJyc2hhcmVkIiwgTVNfU0hBUkVEfE1TX1JFQ1VSU0lWRX0sCgkJeyJyc2xhdmUiLCBNU19TTEFWRXxNU19SRUNVUlNJVkV9LAoJCXsicnByaXZhdGUiLCBNU19TTEFWRXxNU19SRUNVUlNJVkV9LAoJCXsicnVuYmluZGFibGUiLCBNU19VTkJJTkRBQkxFfE1TX1JFQ1VSU0lWRX0sCgkpCgoJLy8gQWx3YXlzIHVuZGVyc3Rvb2QuCgoJeyJybyIsIE1TX1JET05MWX0sICAgICAgICAvLyB2ZnMgZmxhZwoJeyJydyIsIH5NU19SRE9OTFl9LCAgICAgICAvLyB2ZnMgZmxhZwoJeyJyZW1vdW50IiwgTVNfUkVNT1VOVH0sICAvLyBhY3Rpb24gZmxhZwp9OwoKCi8qIEFwcGVuZCBtb3VudCBvcHRpb25zIHRvIHN0cmluZyAqLwpzdGF0aWMgdm9pZCBhcHBlbmRfbW91bnRfb3B0aW9ucyhjaGFyICoqb2xkb3B0cywgY29uc3QgY2hhciAqbmV3b3B0cykKewoJaWYgKCpvbGRvcHRzICYmICoqb2xkb3B0cykgewoJCS8qIGRvIG5vdCBpbnNlcnQgb3B0aW9ucyB3aGljaCBhcmUgYWxyZWFkeSB0aGVyZSAqLwoJCXdoaWxlIChuZXdvcHRzWzBdKSB7CgkJCWNoYXIgKnA7CgkJCWludCBsZW4gPSBzdHJsZW4obmV3b3B0cyk7CgkJCXAgPSBzdHJjaHIobmV3b3B0cywgJywnKTsKCQkJaWYgKHApIGxlbiA9IHAgLSBuZXdvcHRzOwoJCQlwID0gKm9sZG9wdHM7CgkJCXdoaWxlICgxKSB7CgkJCQlpZiAoIXN0cm5jbXAocCwgbmV3b3B0cywgbGVuKQoJCQkJICYmIChwW2xlbl09PScsJyB8fCBwW2xlbl09PTApKQoJCQkJCWdvdG8gc2tpcDsKCQkJCXAgPSBzdHJjaHIocCwnLCcpOwoJCQkJaWYgKCFwKSBicmVhazsKCQkJCXArKzsKCQkJfQoJCQlwID0geGFzcHJpbnRmKCIlcywlLipzIiwgKm9sZG9wdHMsIGxlbiwgbmV3b3B0cyk7CgkJCWZyZWUoKm9sZG9wdHMpOwoJCQkqb2xkb3B0cyA9IHA7CnNraXA6CgkJCW5ld29wdHMgKz0gbGVuOwoJCQl3aGlsZSAobmV3b3B0c1swXSA9PSAnLCcpIG5ld29wdHMrKzsKCQl9Cgl9IGVsc2UgewoJCWlmIChFTkFCTEVfRkVBVFVSRV9DTEVBTl9VUCkgZnJlZSgqb2xkb3B0cyk7CgkJKm9sZG9wdHMgPSB4c3RyZHVwKG5ld29wdHMpOwoJfQp9CgovKiBVc2UgdGhlIG1vdW50X29wdGlvbnMgbGlzdCB0byBwYXJzZSBvcHRpb25zIGludG8gZmxhZ3MuCiAqIEFsc28gcmV0dXJuIGxpc3Qgb2YgdW5yZWNvZ25pemVkIG9wdGlvbnMgaWYgdW5yZWNvZ25pemVkIT1OVUxMICovCnN0YXRpYyBpbnQgcGFyc2VfbW91bnRfb3B0aW9ucyhjaGFyICpvcHRpb25zLCBjaGFyICoqdW5yZWNvZ25pemVkKQp7CglpbnQgZmxhZ3MgPSBNU19TSUxFTlQ7CgoJLy8gTG9vcCB0aHJvdWdoIG9wdGlvbnMKCWZvciAoOzspIHsKCQlpbnQgaTsKCQljaGFyICpjb21tYSA9IHN0cmNocihvcHRpb25zLCAnLCcpOwoKCQlpZiAoY29tbWEpICpjb21tYSA9IDA7CgoJCS8vIEZpbmQgdGhpcyBvcHRpb24gaW4gbW91bnRfb3B0aW9ucwoJCWZvciAoaSA9IDA7IGkgPCBBUlJBWV9TSVpFKG1vdW50X29wdGlvbnMpOyBpKyspIHsKCQkJaWYgKCFzdHJjYXNlY21wKG1vdW50X29wdGlvbnNbaV0ubmFtZSwgb3B0aW9ucykpIHsKCQkJCWxvbmcgZmwgPSBtb3VudF9vcHRpb25zW2ldLmZsYWdzOwoJCQkJaWYgKGZsIDwgMCkgZmxhZ3MgJj0gZmw7CgkJCQllbHNlIGZsYWdzIHw9IGZsOwoJCQkJYnJlYWs7CgkJCX0KCQl9CgkJLy8gSWYgdW5yZWNvZ25pemVkIG5vdCBOVUxMLCBhcHBlbmQgdW5yZWNvZ25pemVkIG1vdW50IG9wdGlvbnMgKi8KCQlpZiAodW5yZWNvZ25pemVkICYmIGkgPT0gQVJSQVlfU0laRShtb3VudF9vcHRpb25zKSkgewoJCQkvLyBBZGQgaXQgdG8gc3RyZmxhZ3MsIHRvIHBhc3Mgb24gdG8ga2VybmVsCgkJCWkgPSAqdW5yZWNvZ25pemVkID8gc3RybGVuKCp1bnJlY29nbml6ZWQpIDogMDsKCQkJKnVucmVjb2duaXplZCA9IHhyZWFsbG9jKCp1bnJlY29nbml6ZWQsIGkrc3RybGVuKG9wdGlvbnMpKzIpOwoKCQkJLy8gQ29tbWEgc2VwYXJhdGVkIGlmIGl0J3Mgbm90IHRoZSBmaXJzdCBvbmUKCQkJaWYgKGkpICgqdW5yZWNvZ25pemVkKVtpKytdID0gJywnOwoJCQlzdHJjcHkoKCp1bnJlY29nbml6ZWQpK2ksIG9wdGlvbnMpOwoJCX0KCgkJaWYgKCFjb21tYSkKCQkJYnJlYWs7CgkJLy8gQWR2YW5jZSB0byBuZXh0IG9wdGlvbgoJCSpjb21tYSA9ICcsJzsKCQlvcHRpb25zID0gKytjb21tYTsKCX0KCglyZXR1cm4gZmxhZ3M7Cn0KCi8vIFJldHVybiBhIGxpc3Qgb2YgYWxsIGJsb2NrIGRldmljZSBiYWNrZWQgZmlsZXN5c3RlbXMKCnN0YXRpYyBsbGlzdF90ICpnZXRfYmxvY2tfYmFja2VkX2ZpbGVzeXN0ZW1zKHZvaWQpCnsKCXN0YXRpYyBjb25zdCBjaGFyIGZpbGVzeXN0ZW1zWzJdW3NpemVvZigiL3Byb2MvZmlsZXN5c3RlbXMiKV0gPSB7CgkJIi9ldGMvZmlsZXN5c3RlbXMiLAoJCSIvcHJvYy9maWxlc3lzdGVtcyIsCgl9OwoJY2hhciAqZnMsICpidWY7CglsbGlzdF90ICpsaXN0ID0gMDsKCWludCBpOwoJRklMRSAqZjsKCglmb3IgKGkgPSAwOyBpIDwgMjsgaSsrKSB7CgkJZiA9IGZvcGVuKGZpbGVzeXN0ZW1zW2ldLCAiciIpOwoJCWlmICghZikgY29udGludWU7CgoJCXdoaWxlICgoYnVmID0geG1hbGxvY19nZXRsaW5lKGYpKSAhPSAwKSB7CgkJCWlmICghc3RybmNtcChidWYsICJub2RldiIsIDUpICYmIGlzc3BhY2UoYnVmWzVdKSkKCQkJCWNvbnRpbnVlOwoJCQlmcyA9IHNraXBfd2hpdGVzcGFjZShidWYpOwoJCQlpZiAoKmZzPT0nIycgfHwgKmZzPT0nKicgfHwgISpmcykgY29udGludWU7CgoJCQlsbGlzdF9hZGRfdG9fZW5kKCZsaXN0LCB4c3RyZHVwKGZzKSk7CgkJCWZyZWUoYnVmKTsKCQl9CgkJaWYgKEVOQUJMRV9GRUFUVVJFX0NMRUFOX1VQKSBmY2xvc2UoZik7Cgl9CgoJcmV0dXJuIGxpc3Q7Cn0KCmxsaXN0X3QgKmZzbGlzdCA9IDA7CgojaWYgRU5BQkxFX0ZFQVRVUkVfQ0xFQU5fVVAKc3RhdGljIHZvaWQgZGVsZXRlX2Jsb2NrX2JhY2tlZF9maWxlc3lzdGVtcyh2b2lkKQp7CglsbGlzdF9mcmVlKGZzbGlzdCwgZnJlZSk7Cn0KI2Vsc2UKdm9pZCBkZWxldGVfYmxvY2tfYmFja2VkX2ZpbGVzeXN0ZW1zKHZvaWQpOwojZW5kaWYKCiNpZiBFTkFCTEVfRkVBVFVSRV9NVEFCX1NVUFBPUlQKc3RhdGljIGludCB1c2VNdGFiID0gMTsKc3RhdGljIGludCBmYWtlSXQ7CiNlbHNlCiNkZWZpbmUgdXNlTXRhYiAwCiNkZWZpbmUgZmFrZUl0IDAKI2VuZGlmCgovLyBQZXJmb3JtIGFjdHVhbCBtb3VudCBvZiBzcGVjaWZpYyBmaWxlc3lzdGVtIGF0IHNwZWNpZmljIGxvY2F0aW9uLgovLyBOQjogbXAtPnh4eCBmaWVsZHMgbWF5IGJlIHRyYXNoZWQgb24gZXhpdApzdGF0aWMgaW50IG1vdW50X2l0X25vdyhzdHJ1Y3QgbW50ZW50ICptcCwgaW50IHZmc2ZsYWdzLCBjaGFyICpmaWx0ZXJvcHRzKQp7CglpbnQgcmMgPSAwOwoKCWlmIChmYWtlSXQpIGdvdG8gbXRhYjsKCgkvLyBNb3VudCwgd2l0aCBmYWxsYmFjayB0byByZWFkLW9ubHkgaWYgbmVjZXNzYXJ5LgoKCWZvciAoOzspIHsKCQlyYyA9IG1vdW50KG1wLT5tbnRfZnNuYW1lLCBtcC0+bW50X2RpciwgbXAtPm1udF90eXBlLAoJCQkJdmZzZmxhZ3MsIGZpbHRlcm9wdHMpOwoJCWlmICghcmMgfHwgKHZmc2ZsYWdzJk1TX1JET05MWSkgfHwgKGVycm5vIT1FQUNDRVMgJiYgZXJybm8hPUVST0ZTKSkKCQkJYnJlYWs7CgkJaWYgKCEodmZzZmxhZ3MgJiBNU19TSUxFTlQpKQoJCQliYl9lcnJvcl9tc2coIiVzIGlzIHdyaXRlLXByb3RlY3RlZCwgbW91bnRpbmcgcmVhZC1vbmx5IiwKCQkJCQkJbXAtPm1udF9mc25hbWUpOwoJCXZmc2ZsYWdzIHw9IE1TX1JET05MWTsKCX0KCgkvLyBBYm9ydCBlbnRpcmVseSBpZiBwZXJtaXNzaW9uIGRlbmllZC4KCglpZiAocmMgJiYgZXJybm8gPT0gRVBFUk0pCgkJYmJfZXJyb3JfbXNnX2FuZF9kaWUoYmJfbXNnX3Blcm1fZGVuaWVkX2FyZV95b3Vfcm9vdCk7CgoJLyogSWYgdGhlIG1vdW50IHdhcyBzdWNjZXNzZnVsLCBhbmQgd2UncmUgbWFpbnRhaW5pbmcgYW4gb2xkLXN0eWxlCgkgKiBtdGFiIGZpbGUgYnkgaGFuZCwgYWRkIHRoZSBuZXcgZW50cnkgdG8gaXQgbm93LiAqLwogbXRhYjoKCWlmIChFTkFCTEVfRkVBVFVSRV9NVEFCX1NVUFBPUlQgJiYgdXNlTXRhYiAmJiAhcmMgJiYgISh2ZnNmbGFncyAmIE1TX1JFTU9VTlQpKSB7CgkJY2hhciAqZnNuYW1lOwoJCUZJTEUgKm1vdW50VGFibGUgPSBzZXRtbnRlbnQoYmJfcGF0aF9tdGFiX2ZpbGUsICJhKyIpOwoJCWludCBpOwoKCQlpZiAoIW1vdW50VGFibGUpIHsKCQkJYmJfZXJyb3JfbXNnKCJubyAlcyIsYmJfcGF0aF9tdGFiX2ZpbGUpOwoJCQlnb3RvIHJldDsKCQl9CgoJCS8vIEFkZCB2ZnMgc3RyaW5nIGZsYWdzCgoJCWZvciAoaT0wOyBtb3VudF9vcHRpb25zW2ldLmZsYWdzICE9IE1TX1JFTU9VTlQ7IGkrKykKCQkJaWYgKG1vdW50X29wdGlvbnNbaV0uZmxhZ3MgPiAwICYmIChtb3VudF9vcHRpb25zW2ldLmZsYWdzICYgdmZzZmxhZ3MpKQoJCQkJYXBwZW5kX21vdW50X29wdGlvbnMoJihtcC0+bW50X29wdHMpLCBtb3VudF9vcHRpb25zW2ldLm5hbWUpOwoKCQkvLyBSZW1vdmUgdHJhaWxpbmcgLyAoaWYgYW55KSBmcm9tIGRpcmVjdG9yeSB3ZSBtb3VudGVkIG9uCgoJCWkgPSBzdHJsZW4obXAtPm1udF9kaXIpIC0gMTsKCQlpZiAoaSA+IDAgJiYgbXAtPm1udF9kaXJbaV0gPT0gJy8nKSBtcC0+bW50X2RpcltpXSA9IDA7CgoJCS8vIENvbnZlcnQgdG8gY2Fub25pY2FsIHBhdGhuYW1lcyBhcyBuZWVkZWQKCgkJbXAtPm1udF9kaXIgPSBiYl9zaW1wbGlmeV9wYXRoKG1wLT5tbnRfZGlyKTsKCQlmc25hbWUgPSAwOwoJCWlmICghbXAtPm1udF90eXBlIHx8ICEqbXAtPm1udF90eXBlKSB7IC8qIGJpbmQgbW91bnQgKi8KCQkJbXAtPm1udF9mc25hbWUgPSBmc25hbWUgPSBiYl9zaW1wbGlmeV9wYXRoKG1wLT5tbnRfZnNuYW1lKTsKCQkJbXAtPm1udF90eXBlID0gKGNoYXIqKSJiaW5kIjsKCQl9CgkJbXAtPm1udF9mcmVxID0gbXAtPm1udF9wYXNzbm8gPSAwOwoKCQkvLyBXcml0ZSBhbmQgY2xvc2UuCgoJCWFkZG1udGVudChtb3VudFRhYmxlLCBtcCk7CgkJZW5kbW50ZW50KG1vdW50VGFibGUpOwoJCWlmIChFTkFCTEVfRkVBVFVSRV9DTEVBTl9VUCkgewoJCQlmcmVlKG1wLT5tbnRfZGlyKTsKCQkJZnJlZShmc25hbWUpOwoJCX0KCX0KIHJldDoKCXJldHVybiByYzsKfQoKI2lmIEVOQUJMRV9GRUFUVVJFX01PVU5UX05GUwoKLyoKICogTGludXggTkZTIG1vdW50CiAqIENvcHlyaWdodCAoQykgMTk5MyBSaWNrIFNsYWRrZXkgPGpyc0B3b3JsZC5zdGQuY29tPgogKgogKiBMaWNlbnNlZCB1bmRlciBHUEx2Miwgc2VlIGZpbGUgTElDRU5TRSBpbiB0aGlzIHRhcmJhbGwgZm9yIGRldGFpbHMuCiAqCiAqIFdlZCBGZWIgIDggMTI6NTE6NDggMTk5NSwgYmlyb0B5Z2dkcmFzaWwuY29tIChSb3NzIEJpcm8pOiBhbGxvdyBhbGwgcG9ydAogKiBudW1iZXJzIHRvIGJlIHNwZWNpZmllZCBvbiB0aGUgY29tbWFuZCBsaW5lLgogKgogKiBGcmksIDggTWFyIDE5OTYgMTg6MDE6MzksIFN3ZW4gVGh1ZW1tbGVyIDxzd2VuQHVuaS1wYWRlcmJvcm4uZGU+OgogKiBPbWl0IHRoZSBjYWxsIHRvIGNvbm5lY3QoKSBmb3IgTGludXggdmVyc2lvbiAxLjMuMTEgb3IgbGF0ZXIuCiAqCiAqIFdlZCBPY3QgIDEgMjM6NTU6MjggMTk5NzogRGljayBTdHJlZWZsYW5kIDxkaWNrX3N0cmVlZmxhbmRAdGFza2luZy5jb20+CiAqIEltcGxlbWVudGVkIHRoZSAiYmciLCAiZmciIGFuZCAicmV0cnkiIG1vdW50IG9wdGlvbnMgZm9yIE5GUy4KICoKICogMTk5OS0wMi0yMiBBcmthZGl1c3ogTWm2a2lld2ljeiA8bWlzaWVrQG1pc2llay5ldS5vcmc+CiAqIC0gYWRkZWQgTmF0aXZlIExhbmd1YWdlIFN1cHBvcnQKICoKICogTW9kaWZpZWQgYnkgT2xhZiBLaXJjaCBhbmQgVHJvbmQgTXlrbGVidXN0IGZvciBuZXcgTkZTIGNvZGUsCiAqIHBsdXMgTkZTdjMgc3R1ZmYuCiAqLwoKLyogVGhpcyBpcyBqdXN0IGEgd2FybmluZyBvZiBhIGNvbW1vbiBtaXN0YWtlLiAgUG9zc2libHkgdGhpcyBzaG91bGQgYmUgYQogKiB1Y2xpYmMgZmFxIGVudHJ5IHJhdGhlciB0aGFuIGluIGJ1c3lib3guLi4gKi8KI2lmIGRlZmluZWQoX19VQ0xJQkNfXykgJiYgISBkZWZpbmVkKF9fVUNMSUJDX0hBU19SUENfXykKI2Vycm9yICJZb3UgbmVlZCB0byBidWlsZCB1Q2xpYmMgd2l0aCBVQ0xJQkNfSEFTX1JQQyBmb3IgTkZTIHN1cHBvcnQuIgojZW5kaWYKCiNkZWZpbmUgTU9VTlRQT1JUIDYzNQojZGVmaW5lIE1OVFBBVEhMRU4gMTAyNAojZGVmaW5lIE1OVE5BTUxFTiAyNTUKI2RlZmluZSBGSFNJWkUgMzIKI2RlZmluZSBGSFNJWkUzIDY0Cgp0eXBlZGVmIGNoYXIgZmhhbmRsZVtGSFNJWkVdOwoKdHlwZWRlZiBzdHJ1Y3QgewoJdW5zaWduZWQgaW50IGZoYW5kbGUzX2xlbjsKCWNoYXIgKmZoYW5kbGUzX3ZhbDsKfSBmaGFuZGxlMzsKCmVudW0gbW91bnRzdGF0MyB7CglNTlRfT0sgPSAwLAoJTU5UM0VSUl9QRVJNID0gMSwKCU1OVDNFUlJfTk9FTlQgPSAyLAoJTU5UM0VSUl9JTyA9IDUsCglNTlQzRVJSX0FDQ0VTID0gMTMsCglNTlQzRVJSX05PVERJUiA9IDIwLAoJTU5UM0VSUl9JTlZBTCA9IDIyLAoJTU5UM0VSUl9OQU1FVE9PTE9ORyA9IDYzLAoJTU5UM0VSUl9OT1RTVVBQID0gMTAwMDQsCglNTlQzRVJSX1NFUlZFUkZBVUxUID0gMTAwMDYsCn07CnR5cGVkZWYgZW51bSBtb3VudHN0YXQzIG1vdW50c3RhdDM7CgpzdHJ1Y3QgZmhzdGF0dXMgewoJdW5zaWduZWQgaW50IGZoc19zdGF0dXM7Cgl1bmlvbiB7CgkJZmhhbmRsZSBmaHNfZmhhbmRsZTsKCX0gZmhzdGF0dXNfdTsKfTsKdHlwZWRlZiBzdHJ1Y3QgZmhzdGF0dXMgZmhzdGF0dXM7CgpzdHJ1Y3QgbW91bnRyZXMzX29rIHsKCWZoYW5kbGUzIGZoYW5kbGU7CglzdHJ1Y3QgewoJCXVuc2lnbmVkIGludCBhdXRoX2ZsYXZvdXJzX2xlbjsKCQljaGFyICphdXRoX2ZsYXZvdXJzX3ZhbDsKCX0gYXV0aF9mbGF2b3VyczsKfTsKdHlwZWRlZiBzdHJ1Y3QgbW91bnRyZXMzX29rIG1vdW50cmVzM19vazsKCnN0cnVjdCBtb3VudHJlczMgewoJbW91bnRzdGF0MyBmaHNfc3RhdHVzOwoJdW5pb24gewoJCW1vdW50cmVzM19vayBtb3VudGluZm87Cgl9IG1vdW50cmVzM191Owp9Owp0eXBlZGVmIHN0cnVjdCBtb3VudHJlczMgbW91bnRyZXMzOwoKdHlwZWRlZiBjaGFyICpkaXJwYXRoOwoKdHlwZWRlZiBjaGFyICpuYW1lOwoKdHlwZWRlZiBzdHJ1Y3QgbW91bnRib2R5ICptb3VudGxpc3Q7CgpzdHJ1Y3QgbW91bnRib2R5IHsKCW5hbWUgbWxfaG9zdG5hbWU7CglkaXJwYXRoIG1sX2RpcmVjdG9yeTsKCW1vdW50bGlzdCBtbF9uZXh0Owp9Owp0eXBlZGVmIHN0cnVjdCBtb3VudGJvZHkgbW91bnRib2R5OwoKdHlwZWRlZiBzdHJ1Y3QgZ3JvdXBub2RlICpncm91cHM7CgpzdHJ1Y3QgZ3JvdXBub2RlIHsKCW5hbWUgZ3JfbmFtZTsKCWdyb3VwcyBncl9uZXh0Owp9Owp0eXBlZGVmIHN0cnVjdCBncm91cG5vZGUgZ3JvdXBub2RlOwoKdHlwZWRlZiBzdHJ1Y3QgZXhwb3J0bm9kZSAqZXhwb3J0czsKCnN0cnVjdCBleHBvcnRub2RlIHsKCWRpcnBhdGggZXhfZGlyOwoJZ3JvdXBzIGV4X2dyb3VwczsKCWV4cG9ydHMgZXhfbmV4dDsKfTsKdHlwZWRlZiBzdHJ1Y3QgZXhwb3J0bm9kZSBleHBvcnRub2RlOwoKc3RydWN0IHBwYXRoY25mIHsKCWludCBwY19saW5rX21heDsKCXNob3J0IHBjX21heF9jYW5vbjsKCXNob3J0IHBjX21heF9pbnB1dDsKCXNob3J0IHBjX25hbWVfbWF4OwoJc2hvcnQgcGNfcGF0aF9tYXg7CglzaG9ydCBwY19waXBlX2J1ZjsKCXVpbnQ4X3QgcGNfdmRpc2FibGU7CgljaGFyIHBjX3h4eDsKCXNob3J0IHBjX21hc2tbMl07Cn07CnR5cGVkZWYgc3RydWN0IHBwYXRoY25mIHBwYXRoY25mOwoKI2RlZmluZSBNT1VOVFBST0cgMTAwMDA1CiNkZWZpbmUgTU9VTlRWRVJTIDEKCiNkZWZpbmUgTU9VTlRQUk9DX05VTEwgMAojZGVmaW5lIE1PVU5UUFJPQ19NTlQgMQojZGVmaW5lIE1PVU5UUFJPQ19EVU1QIDIKI2RlZmluZSBNT1VOVFBST0NfVU1OVCAzCiNkZWZpbmUgTU9VTlRQUk9DX1VNTlRBTEwgNAojZGVmaW5lIE1PVU5UUFJPQ19FWFBPUlQgNQojZGVmaW5lIE1PVU5UUFJPQ19FWFBPUlRBTEwgNgoKI2RlZmluZSBNT1VOVFZFUlNfUE9TSVggMgoKI2RlZmluZSBNT1VOVFBST0NfUEFUSENPTkYgNwoKI2RlZmluZSBNT1VOVF9WMyAzCgojZGVmaW5lIE1PVU5UUFJPQzNfTlVMTCAwCiNkZWZpbmUgTU9VTlRQUk9DM19NTlQgMQojZGVmaW5lIE1PVU5UUFJPQzNfRFVNUCAyCiNkZWZpbmUgTU9VTlRQUk9DM19VTU5UIDMKI2RlZmluZSBNT1VOVFBST0MzX1VNTlRBTEwgNAojZGVmaW5lIE1PVU5UUFJPQzNfRVhQT1JUIDUKCmVudW0gewojaWZuZGVmIE5GU19GSFNJWkUKCU5GU19GSFNJWkUgPSAzMiwKI2VuZGlmCiNpZm5kZWYgTkZTX1BPUlQKCU5GU19QT1JUID0gMjA0OQojZW5kaWYKfTsKCi8qCiAqIFdlIHdhbnQgdG8gYmUgYWJsZSB0byBjb21waWxlIG1vdW50IG9uIG9sZCBrZXJuZWxzIGluIHN1Y2ggYSB3YXkKICogdGhhdCB0aGUgYmluYXJ5IHdpbGwgd29yayB3ZWxsIG9uIG1vcmUgcmVjZW50IGtlcm5lbHMuCiAqIFRodXMsIGlmIG5lY2Vzc2FyeSB3ZSB0ZWFjaCBuZnNtb3VudC5jIHRoZSBzdHJ1Y3R1cmUgb2YgbmV3IGZpZWxkcwogKiB0aGF0IHdpbGwgY29tZSBsYXRlci4KICoKICogTW9yZW92ZXIsIHRoZSBuZXcga2VybmVsIGluY2x1ZGVzIGNvbmZsaWN0IHdpdGggZ2xpYmMgaW5jbHVkZXMKICogc28gaXQgaXMgZWFzaWVzdCB0byBpZ25vcmUgdGhlIGtlcm5lbCBhbHRvZ2V0aGVyIChhdCBjb21waWxlIHRpbWUpLgogKi8KCnN0cnVjdCBuZnMyX2ZoIHsKCWNoYXIgICAgICAgICAgICAgICAgICAgIGRhdGFbMzJdOwp9OwpzdHJ1Y3QgbmZzM19maCB7Cgl1bnNpZ25lZCBzaG9ydCAgICAgICAgICBzaXplOwoJdW5zaWduZWQgY2hhciAgICAgICAgICAgZGF0YVs2NF07Cn07CgpzdHJ1Y3QgbmZzX21vdW50X2RhdGEgewoJaW50CQl2ZXJzaW9uOwkJLyogMSAqLwoJaW50CQlmZDsJCQkvKiAxICovCglzdHJ1Y3QgbmZzMl9maAlvbGRfcm9vdDsJCS8qIDEgKi8KCWludAkJZmxhZ3M7CQkJLyogMSAqLwoJaW50CQlyc2l6ZTsJCQkvKiAxICovCglpbnQJCXdzaXplOwkJCS8qIDEgKi8KCWludAkJdGltZW87CQkJLyogMSAqLwoJaW50CQlyZXRyYW5zOwkJLyogMSAqLwoJaW50CQlhY3JlZ21pbjsJCS8qIDEgKi8KCWludAkJYWNyZWdtYXg7CQkvKiAxICovCglpbnQJCWFjZGlybWluOwkJLyogMSAqLwoJaW50CQlhY2Rpcm1heDsJCS8qIDEgKi8KCXN0cnVjdCBzb2NrYWRkcl9pbiBhZGRyOwkJLyogMSAqLwoJY2hhcgkJaG9zdG5hbWVbMjU2XTsJCS8qIDEgKi8KCWludAkJbmFtbGVuOwkJCS8qIDIgKi8KCXVuc2lnbmVkIGludAlic2l6ZTsJCQkvKiAzICovCglzdHJ1Y3QgbmZzM19maAlyb290OwkJCS8qIDQgKi8KfTsKCi8qIGJpdHMgaW4gdGhlIGZsYWdzIGZpZWxkICovCmVudW0gewoJTkZTX01PVU5UX1NPRlQgPSAweDAwMDEsCS8qIDEgKi8KCU5GU19NT1VOVF9JTlRSID0gMHgwMDAyLAkvKiAxICovCglORlNfTU9VTlRfU0VDVVJFID0gMHgwMDA0LAkvKiAxICovCglORlNfTU9VTlRfUE9TSVggPSAweDAwMDgsCS8qIDEgKi8KCU5GU19NT1VOVF9OT0NUTyA9IDB4MDAxMCwJLyogMSAqLwoJTkZTX01PVU5UX05PQUMgPSAweDAwMjAsCS8qIDEgKi8KCU5GU19NT1VOVF9UQ1AgPSAweDAwNDAsCQkvKiAyICovCglORlNfTU9VTlRfVkVSMyA9IDB4MDA4MCwJLyogMyAqLwoJTkZTX01PVU5UX0tFUkJFUk9TID0gMHgwMTAwLAkvKiAzICovCglORlNfTU9VTlRfTk9OTE0gPSAweDAyMDAJLyogMyAqLwp9OwoKCi8qCiAqIFdlIG5lZWQgdG8gdHJhbnNsYXRlIGJldHdlZW4gbmZzIHN0YXR1cyByZXR1cm4gdmFsdWVzIGFuZAogKiB0aGUgbG9jYWwgZXJybm8gdmFsdWVzIHdoaWNoIG1heSBub3QgYmUgdGhlIHNhbWUuCiAqCiAqIEFuZHJlYXMgU2Nod2FiIDxzY2h3YWJATFM1LmluZm9ybWF0aWsudW5pLWRvcnRtdW5kLmRlPjogY2hhbmdlIGVycm5vOgogKiAiYWZ0ZXIgI2luY2x1ZGUgPGVycm5vLmg+IHRoZSBzeW1ib2wgZXJybm8gaXMgcmVzZXJ2ZWQgZm9yIGFueSB1c2UsCiAqICBpdCBjYW5ub3QgZXZlbiBiZSB1c2VkIGFzIGEgc3RydWN0IHRhZyBvciBmaWVsZCBuYW1lIi4KICovCgojaWZuZGVmIEVEUVVPVAojZGVmaW5lIEVEUVVPVAlFTk9TUEMKI2VuZGlmCgovLyBDb252ZXJ0IGVhY2ggTkZTRVJSX0JMQUggaW50byBFQkxBSAoKc3RhdGljIGNvbnN0IHN0cnVjdCB7CglpbnQgc3RhdDsKCWludCBlcnJudW07Cn0gbmZzX2VycnRibFtdID0gewoJezAsMH0sIHsxLEVQRVJNfSwgezIsRU5PRU5UfSwgezUsRUlPfSwgezYsRU5YSU99LCB7MTMsRUFDQ0VTfSwgezE3LEVFWElTVH0sCgl7MTksRU5PREVWfSwgezIwLEVOT1RESVJ9LCB7MjEsRUlTRElSfSwgezIyLEVJTlZBTH0sIHsyNyxFRkJJR30sCgl7MjgsRU5PU1BDfSwgezMwLEVST0ZTfSwgezYzLEVOQU1FVE9PTE9OR30sIHs2NixFTk9URU1QVFl9LCB7NjksRURRVU9UfSwKCXs3MCxFU1RBTEV9LCB7NzEsRVJFTU9URX0sIHstMSxFSU99Cn07CgpzdGF0aWMgY2hhciAqbmZzX3N0cmVycm9yKGludCBzdGF0dXMpCnsKCWludCBpOwoJc3RhdGljIGNoYXIgYnVmW3NpemVvZigidW5rbm93biBuZnMgc3RhdHVzIHJldHVybiB2YWx1ZTogIikgKyBzaXplb2YoaW50KSozXTsKCglmb3IgKGkgPSAwOyBuZnNfZXJydGJsW2ldLnN0YXQgIT0gLTE7IGkrKykgewoJCWlmIChuZnNfZXJydGJsW2ldLnN0YXQgPT0gc3RhdHVzKQoJCQlyZXR1cm4gc3RyZXJyb3IobmZzX2VycnRibFtpXS5lcnJudW0pOwoJfQoJc3ByaW50ZihidWYsICJ1bmtub3duIG5mcyBzdGF0dXMgcmV0dXJuIHZhbHVlOiAlZCIsIHN0YXR1cyk7CglyZXR1cm4gYnVmOwp9CgpzdGF0aWMgYm9vbF90IHhkcl9maGFuZGxlKFhEUiAqeGRycywgZmhhbmRsZSBvYmpwKQp7CglpZiAoIXhkcl9vcGFxdWUoeGRycywgb2JqcCwgRkhTSVpFKSkKCQkgcmV0dXJuIEZBTFNFOwoJcmV0dXJuIFRSVUU7Cn0KCnN0YXRpYyBib29sX3QgeGRyX2Zoc3RhdHVzKFhEUiAqeGRycywgZmhzdGF0dXMgKm9ianApCnsKCWlmICgheGRyX3VfaW50KHhkcnMsICZvYmpwLT5maHNfc3RhdHVzKSkKCQkgcmV0dXJuIEZBTFNFOwoJc3dpdGNoIChvYmpwLT5maHNfc3RhdHVzKSB7CgljYXNlIDA6CgkJaWYgKCF4ZHJfZmhhbmRsZSh4ZHJzLCBvYmpwLT5maHN0YXR1c191LmZoc19maGFuZGxlKSkKCQkJIHJldHVybiBGQUxTRTsKCQlicmVhazsKCWRlZmF1bHQ6CgkJYnJlYWs7Cgl9CglyZXR1cm4gVFJVRTsKfQoKc3RhdGljIGJvb2xfdCB4ZHJfZGlycGF0aChYRFIgKnhkcnMsIGRpcnBhdGggKm9ianApCnsKCWlmICgheGRyX3N0cmluZyh4ZHJzLCBvYmpwLCBNTlRQQVRITEVOKSkKCQkgcmV0dXJuIEZBTFNFOwoJcmV0dXJuIFRSVUU7Cn0KCnN0YXRpYyBib29sX3QgeGRyX2ZoYW5kbGUzKFhEUiAqeGRycywgZmhhbmRsZTMgKm9ianApCnsKCWlmICgheGRyX2J5dGVzKHhkcnMsIChjaGFyICoqKSZvYmpwLT5maGFuZGxlM192YWwsICh1bnNpZ25lZCBpbnQgKikgJm9ianAtPmZoYW5kbGUzX2xlbiwgRkhTSVpFMykpCgkJIHJldHVybiBGQUxTRTsKCXJldHVybiBUUlVFOwp9CgpzdGF0aWMgYm9vbF90IHhkcl9tb3VudHJlczNfb2soWERSICp4ZHJzLCBtb3VudHJlczNfb2sgKm9ianApCnsKCWlmICgheGRyX2ZoYW5kbGUzKHhkcnMsICZvYmpwLT5maGFuZGxlKSkKCQlyZXR1cm4gRkFMU0U7CglpZiAoIXhkcl9hcnJheSh4ZHJzLCAmKG9ianAtPmF1dGhfZmxhdm91cnMuYXV0aF9mbGF2b3Vyc192YWwpLCAmKG9ianAtPmF1dGhfZmxhdm91cnMuYXV0aF9mbGF2b3Vyc19sZW4pLCB+MCwKCQkJCXNpemVvZiAoaW50KSwgKHhkcnByb2NfdCkgeGRyX2ludCkpCgkJcmV0dXJuIEZBTFNFOwoJcmV0dXJuIFRSVUU7Cn0KCnN0YXRpYyBib29sX3QgeGRyX21vdW50c3RhdDMoWERSICp4ZHJzLCBtb3VudHN0YXQzICpvYmpwKQp7CglpZiAoIXhkcl9lbnVtKHhkcnMsIChlbnVtX3QgKikgb2JqcCkpCgkJIHJldHVybiBGQUxTRTsKCXJldHVybiBUUlVFOwp9CgpzdGF0aWMgYm9vbF90IHhkcl9tb3VudHJlczMoWERSICp4ZHJzLCBtb3VudHJlczMgKm9ianApCnsKCWlmICgheGRyX21vdW50c3RhdDMoeGRycywgJm9ianAtPmZoc19zdGF0dXMpKQoJCXJldHVybiBGQUxTRTsKCXN3aXRjaCAob2JqcC0+ZmhzX3N0YXR1cykgewoJY2FzZSBNTlRfT0s6CgkJaWYgKCF4ZHJfbW91bnRyZXMzX29rKHhkcnMsICZvYmpwLT5tb3VudHJlczNfdS5tb3VudGluZm8pKQoJCQkgcmV0dXJuIEZBTFNFOwoJCWJyZWFrOwoJZGVmYXVsdDoKCQlicmVhazsKCX0KCXJldHVybiBUUlVFOwp9CgojZGVmaW5lIE1BWF9ORlNQUk9UICgobmZzX21vdW50X3ZlcnNpb24gPj0gNCkgPyAzIDogMikKCi8qCiAqIG5mc19tb3VudF92ZXJzaW9uIGFjY29yZGluZyB0byB0aGUgc291cmNlcyBzZWVuIGF0IGNvbXBpbGUgdGltZS4KICovCnN0YXRpYyBpbnQgbmZzX21vdW50X3ZlcnNpb247CnN0YXRpYyBpbnQga2VybmVsX3ZlcnNpb247CgovKgogKiBVbmZvcnR1bmF0ZWx5LCB0aGUga2VybmVsIHByaW50cyBhbm5veWluZyBjb25zb2xlIG1lc3NhZ2VzCiAqIGluIGNhc2Ugb2YgYW4gdW5leHBlY3RlZCBuZnMgbW91bnQgdmVyc2lvbiAoaW5zdGVhZCBvZgogKiBqdXN0IHJldHVybmluZyBzb21lIGVycm9yKS4gIFRoZXJlZm9yZSB3ZSdsbCBoYXZlIHRvIHRyeQogKiBhbmQgZmlndXJlIG91dCB3aGF0IHZlcnNpb24gdGhlIGtlcm5lbCBleHBlY3RzLgogKgogKiBWYXJpYWJsZXM6CiAqCUtFUk5FTF9ORlNfTU9VTlRfVkVSU0lPTjoga2VybmVsIHNvdXJjZXMgYXQgY29tcGlsZSB0aW1lCiAqCU5GU19NT1VOVF9WRVJTSU9OOiB0aGVzZSBuZnNtb3VudCBzb3VyY2VzIGF0IGNvbXBpbGUgdGltZQogKgluZnNfbW91bnRfdmVyc2lvbjogdmVyc2lvbiB0aGlzIHNvdXJjZSBhbmQgcnVubmluZyBrZXJuZWwgY2FuIGhhbmRsZQogKi8Kc3RhdGljIHZvaWQKZmluZF9rZXJuZWxfbmZzX21vdW50X3ZlcnNpb24odm9pZCkKewoJaWYgKGtlcm5lbF92ZXJzaW9uKQoJCXJldHVybjsKCgluZnNfbW91bnRfdmVyc2lvbiA9IDQ7IC8qIGRlZmF1bHQgKi8KCglrZXJuZWxfdmVyc2lvbiA9IGdldF9saW51eF92ZXJzaW9uX2NvZGUoKTsKCWlmIChrZXJuZWxfdmVyc2lvbikgewoJCWlmIChrZXJuZWxfdmVyc2lvbiA8IEtFUk5FTF9WRVJTSU9OKDIsMSwzMikpCgkJCW5mc19tb3VudF92ZXJzaW9uID0gMTsKCQllbHNlIGlmIChrZXJuZWxfdmVyc2lvbiA8IEtFUk5FTF9WRVJTSU9OKDIsMiwxOCkgfHwKCQkJCShrZXJuZWxfdmVyc2lvbiA+PSBLRVJORUxfVkVSU0lPTigyLDMsMCkgJiYKCQkJCSBrZXJuZWxfdmVyc2lvbiA8IEtFUk5FTF9WRVJTSU9OKDIsMyw5OSkpKQoJCQluZnNfbW91bnRfdmVyc2lvbiA9IDM7CgkJLyogZWxzZSB2NCBzaW5jZSAyLjMuOTlwcmU0ICovCgl9Cn0KCnN0YXRpYyBzdHJ1Y3QgcG1hcCAqCmdldF9tb3VudHBvcnQoc3RydWN0IHNvY2thZGRyX2luICpzZXJ2ZXJfYWRkciwKCWxvbmcgdW5zaWduZWQgcHJvZywKCWxvbmcgdW5zaWduZWQgdmVyc2lvbiwKCWxvbmcgdW5zaWduZWQgcHJvdG8sCglsb25nIHVuc2lnbmVkIHBvcnQpCnsKCXN0cnVjdCBwbWFwbGlzdCAqcG1hcDsKCXN0YXRpYyBzdHJ1Y3QgcG1hcCBwID0gezAsIDAsIDAsIDB9OwoKCXNlcnZlcl9hZGRyLT5zaW5fcG9ydCA9IFBNQVBQT1JUOwovKiBnbGliYyAyLjQgKHN0aWxsKSBoYXMgcG1hcF9nZXRtYXBzKHN0cnVjdCBzb2NrYWRkcl9pbiAqKS4KICogSSB1bmRlcnN0YW5kIGl0IGxpa2UgIklQdjYgZm9yIHRoaXMgaXMgbm90IDEwMCUgcmVhZHkiICovCglwbWFwID0gcG1hcF9nZXRtYXBzKHNlcnZlcl9hZGRyKTsKCglpZiAodmVyc2lvbiA+IE1BWF9ORlNQUk9UKQoJCXZlcnNpb24gPSBNQVhfTkZTUFJPVDsKCWlmICghcHJvZykKCQlwcm9nID0gTU9VTlRQUk9HOwoJcC5wbV9wcm9nID0gcHJvZzsKCXAucG1fdmVycyA9IHZlcnNpb247CglwLnBtX3Byb3QgPSBwcm90bzsKCXAucG1fcG9ydCA9IHBvcnQ7CgoJd2hpbGUgKHBtYXApIHsKCQlpZiAocG1hcC0+cG1sX21hcC5wbV9wcm9nICE9IHByb2cpCgkJCWdvdG8gbmV4dDsKCQlpZiAoIXZlcnNpb24gJiYgcC5wbV92ZXJzID4gcG1hcC0+cG1sX21hcC5wbV92ZXJzKQoJCQlnb3RvIG5leHQ7CgkJaWYgKHZlcnNpb24gPiAyICYmIHBtYXAtPnBtbF9tYXAucG1fdmVycyAhPSB2ZXJzaW9uKQoJCQlnb3RvIG5leHQ7CgkJaWYgKHZlcnNpb24gJiYgdmVyc2lvbiA8PSAyICYmIHBtYXAtPnBtbF9tYXAucG1fdmVycyA+IDIpCgkJCWdvdG8gbmV4dDsKCQlpZiAocG1hcC0+cG1sX21hcC5wbV92ZXJzID4gTUFYX05GU1BST1QgfHwKCQkgICAgKHByb3RvICYmIHAucG1fcHJvdCAmJiBwbWFwLT5wbWxfbWFwLnBtX3Byb3QgIT0gcHJvdG8pIHx8CgkJICAgIChwb3J0ICYmIHBtYXAtPnBtbF9tYXAucG1fcG9ydCAhPSBwb3J0KSkKCQkJZ290byBuZXh0OwoJCW1lbWNweSgmcCwgJnBtYXAtPnBtbF9tYXAsIHNpemVvZihwKSk7Cm5leHQ6CgkJcG1hcCA9IHBtYXAtPnBtbF9uZXh0OwoJfQoJaWYgKCFwLnBtX3ZlcnMpCgkJcC5wbV92ZXJzID0gTU9VTlRWRVJTOwoJaWYgKCFwLnBtX3BvcnQpCgkJcC5wbV9wb3J0ID0gTU9VTlRQT1JUOwoJaWYgKCFwLnBtX3Byb3QpCgkJcC5wbV9wcm90ID0gSVBQUk9UT19UQ1A7CglyZXR1cm4gJnA7Cn0KCiNpZiBCQl9NTVUKc3RhdGljIGludCBkYWVtb25pemUodm9pZCkKewoJaW50IGZkOwoJaW50IHBpZCA9IGZvcmsoKTsKCWlmIChwaWQgPCAwKSAvKiBlcnJvciAqLwoJCXJldHVybiAtZXJybm87CglpZiAocGlkID4gMCkgLyogcGFyZW50ICovCgkJcmV0dXJuIDA7CgkvKiBjaGlsZCAqLwoJZmQgPSB4b3BlbihiYl9kZXZfbnVsbCwgT19SRFdSKTsKCWR1cDIoZmQsIDApOwoJZHVwMihmZCwgMSk7CglkdXAyKGZkLCAyKTsKCXdoaWxlIChmZCA+IDIpIGNsb3NlKGZkLS0pOwoJc2V0c2lkKCk7CglvcGVubG9nKGFwcGxldF9uYW1lLCBMT0dfUElELCBMT0dfREFFTU9OKTsKCWxvZ21vZGUgPSBMT0dNT0RFX1NZU0xPRzsKCXJldHVybiAxOwp9CiNlbHNlCnN0YXRpYyBpbmxpbmUgaW50IGRhZW1vbml6ZSh2b2lkKSB7IHJldHVybiAtRU5PU1lTOyB9CiNlbmRpZgoKLy8gVE9ETwpzdGF0aWMgaW5saW5lIGludCB3ZV9zYXdfdGhpc19ob3N0X2JlZm9yZShjb25zdCBjaGFyICpob3N0bmFtZSkKewoJcmV0dXJuIDA7Cn0KCi8qIFJQQyBzdHJlcnJvciBhbmFsb2dzIGFyZSB0ZXJtaW5hbGx5IGlkaW90aWM6CiAqICptYW5kYXRvcnkqIHByZWZpeCBhbmQgXG4gYXQgZW5kLgogKiBUaGlzIGhvcGVmdWxseSBoZWxwcy4gVXNhZ2U6CiAqIGVycm9yX21zZ19ycGMoY2xudF8qZXJyb3IqKCIgIikpICovCnN0YXRpYyB2b2lkIGVycm9yX21zZ19ycGMoY29uc3QgY2hhciAqbXNnKQp7CglpbnQgbGVuOwoJd2hpbGUgKG1zZ1swXSA9PSAnICcgfHwgbXNnWzBdID09ICc6JykgbXNnKys7CglsZW4gPSBzdHJsZW4obXNnKTsKCXdoaWxlIChsZW4gJiYgbXNnW2xlbi0xXSA9PSAnXG4nKSBsZW4tLTsKCWJiX2Vycm9yX21zZygiJS4qcyIsIGxlbiwgbXNnKTsKfQoKLy8gTkI6IG1wLT54eHggZmllbGRzIG1heSBiZSB0cmFzaGVkIG9uIGV4aXQKc3RhdGljIGludCBuZnNtb3VudChzdHJ1Y3QgbW50ZW50ICptcCwgaW50IHZmc2ZsYWdzLCBjaGFyICpmaWx0ZXJvcHRzKQp7CglDTElFTlQgKm1jbGllbnQ7CgljaGFyICpob3N0bmFtZTsKCWNoYXIgKnBhdGhuYW1lOwoJY2hhciAqbW91bnRob3N0OwoJc3RydWN0IG5mc19tb3VudF9kYXRhIGRhdGE7CgljaGFyICpvcHQ7CglzdHJ1Y3QgaG9zdGVudCAqaHA7CglzdHJ1Y3Qgc29ja2FkZHJfaW4gc2VydmVyX2FkZHI7CglzdHJ1Y3Qgc29ja2FkZHJfaW4gbW91bnRfc2VydmVyX2FkZHI7CglpbnQgbXNvY2ssIGZzb2NrOwoJdW5pb24gewoJCXN0cnVjdCBmaHN0YXR1cyBuZnN2MjsKCQlzdHJ1Y3QgbW91bnRyZXMzIG5mc3YzOwoJfSBzdGF0dXM7CglpbnQgZGFlbW9uaXplZDsKCWNoYXIgKnM7CglpbnQgcG9ydDsKCWludCBtb3VudHBvcnQ7CglpbnQgcHJvdG87CiNpZiBCQl9NTVUKCWludCBiZyA9IDA7CiNlbHNlCgllbnVtIHsgYmcgPSAwIH07CiNlbmRpZgoJaW50IHNvZnQ7CglpbnQgaW50cjsKCWludCBwb3NpeDsKCWludCBub2N0bzsKCWludCBub2FjOwoJaW50IG5vbG9jazsKCWludCByZXRyeTsKCWludCB0Y3A7CglpbnQgbW91bnRwcm9nOwoJaW50IG1vdW50dmVyczsKCWludCBuZnNwcm9nOwoJaW50IG5mc3ZlcnM7CglpbnQgcmV0dmFsOwoKCWZpbmRfa2VybmVsX25mc19tb3VudF92ZXJzaW9uKCk7CgoJZGFlbW9uaXplZCA9IDA7Cgltb3VudGhvc3QgPSBOVUxMOwoJcmV0dmFsID0gRVRJTUVET1VUOwoJbXNvY2sgPSBmc29jayA9IC0xOwoJbWNsaWVudCA9IE5VTEw7CgoJLyogTkI6IGhvc3RuYW1lLCBtb3VudGhvc3QsIGZpbHRlcm9wdHMgbXVzdCBiZSBmcmVlKClkIHByaW9yIHRvIHJldHVybiAqLwoKCWZpbHRlcm9wdHMgPSB4c3RyZHVwKGZpbHRlcm9wdHMpOyAvKiBnb2luZyB0byB0cmFzaCBpdCBsYXRlci4uLiAqLwoKCWhvc3RuYW1lID0geHN0cmR1cChtcC0+bW50X2ZzbmFtZSk7CgkvKiBtb3VudF9tYWluKCkgZ3VhcmFudGVlcyB0aGF0ICc6JyBpcyB0aGVyZSAqLwoJcyA9IHN0cmNocihob3N0bmFtZSwgJzonKTsKCXBhdGhuYW1lID0gcyArIDE7CgkqcyA9ICdcMCc7CgkvKiBJZ25vcmUgYWxsIGJ1dCBmaXJzdCBob3N0bmFtZSBpbiByZXBsaWNhdGVkIG1vdW50cwoJICAgdW50aWwgdGhleSBjYW4gYmUgZnVsbHkgc3VwcG9ydGVkLiAobWFja0BzZ2kuY29tKSAqLwoJcyA9IHN0cmNocihob3N0bmFtZSwgJywnKTsKCWlmIChzKSB7CgkJKnMgPSAnXDAnOwoJCWJiX2Vycm9yX21zZygid2FybmluZzogbXVsdGlwbGUgaG9zdG5hbWVzIG5vdCBzdXBwb3J0ZWQiKTsKCX0KCglzZXJ2ZXJfYWRkci5zaW5fZmFtaWx5ID0gQUZfSU5FVDsKCWlmICghaW5ldF9hdG9uKGhvc3RuYW1lLCAmc2VydmVyX2FkZHIuc2luX2FkZHIpKSB7CgkJaHAgPSBnZXRob3N0YnluYW1lKGhvc3RuYW1lKTsKCQlpZiAoaHAgPT0gTlVMTCkgewoJCQliYl9oZXJyb3JfbXNnKCIlcyIsIGhvc3RuYW1lKTsKCQkJZ290byBmYWlsOwoJCX0KCQlpZiAoaHAtPmhfbGVuZ3RoID4gc2l6ZW9mKHN0cnVjdCBpbl9hZGRyKSkgewoJCQliYl9lcnJvcl9tc2coImdvdCBiYWQgaHAtPmhfbGVuZ3RoIik7CgkJCWhwLT5oX2xlbmd0aCA9IHNpemVvZihzdHJ1Y3QgaW5fYWRkcik7CgkJfQoJCW1lbWNweSgmc2VydmVyX2FkZHIuc2luX2FkZHIsCgkJCQlocC0+aF9hZGRyLCBocC0+aF9sZW5ndGgpOwoJfQoKCW1lbWNweSgmbW91bnRfc2VydmVyX2FkZHIsICZzZXJ2ZXJfYWRkciwgc2l6ZW9mKG1vdW50X3NlcnZlcl9hZGRyKSk7CgoJLyogYWRkIElQIGFkZHJlc3MgdG8gbXRhYiBvcHRpb25zIGZvciB1c2Ugd2hlbiB1bm1vdW50aW5nICovCgoJaWYgKCFtcC0+bW50X29wdHMpIHsgLyogVE9ETzogYWN0dWFsbHkgbXAtPm1udF9vcHRzIGlzIG5ldmVyIE5VTEwgKi8KCQltcC0+bW50X29wdHMgPSB4YXNwcmludGYoImFkZHI9JXMiLCBpbmV0X250b2Eoc2VydmVyX2FkZHIuc2luX2FkZHIpKTsKCX0gZWxzZSB7CgkJY2hhciAqdG1wID0geGFzcHJpbnRmKCIlcyVzYWRkcj0lcyIsIG1wLT5tbnRfb3B0cywKCQkJCQltcC0+bW50X29wdHNbMF0gPyAiLCIgOiAiIiwKCQkJCQlpbmV0X250b2Eoc2VydmVyX2FkZHIuc2luX2FkZHIpKTsKCQlmcmVlKG1wLT5tbnRfb3B0cyk7CgkJbXAtPm1udF9vcHRzID0gdG1wOwoJfQoKCS8qIFNldCBkZWZhdWx0IG9wdGlvbnMuCgkgKiByc2l6ZS93c2l6ZSAoYW5kIGJzaXplLCBmb3IgdmVyID49IDMpIGFyZSBsZWZ0IDAgaW4gb3JkZXIgdG8KCSAqIGxldCB0aGUga2VybmVsIGRlY2lkZS4KCSAqIHRpbWVvIGlzIGZpbGxlZCBpbiBhZnRlciB3ZSBrbm93IHdoZXRoZXIgaXQnbGwgYmUgVENQIG9yIFVEUC4gKi8KCW1lbXNldCgmZGF0YSwgMCwgc2l6ZW9mKGRhdGEpKTsKCWRhdGEucmV0cmFucwk9IDM7CglkYXRhLmFjcmVnbWluCT0gMzsKCWRhdGEuYWNyZWdtYXgJPSA2MDsKCWRhdGEuYWNkaXJtaW4JPSAzMDsKCWRhdGEuYWNkaXJtYXgJPSA2MDsKCWRhdGEubmFtbGVuCT0gTkFNRV9NQVg7CgoJc29mdCA9IDA7CglpbnRyID0gMDsKCXBvc2l4ID0gMDsKCW5vY3RvID0gMDsKCW5vbG9jayA9IDA7Cglub2FjID0gMDsKCXJldHJ5ID0gMTAwMDA7CQkvKiAxMDAwMCBtaW51dGVzIH4gMSB3ZWVrICovCgl0Y3AgPSAwOwoKCW1vdW50cHJvZyA9IE1PVU5UUFJPRzsKCW1vdW50dmVycyA9IDA7Cglwb3J0ID0gMDsKCW1vdW50cG9ydCA9IDA7CgluZnNwcm9nID0gMTAwMDAzOwoJbmZzdmVycyA9IDA7CgoJLyogcGFyc2Ugb3B0aW9ucyAqLwoJaWYgKGZpbHRlcm9wdHMpCWZvciAob3B0ID0gc3RydG9rKGZpbHRlcm9wdHMsICIsIik7IG9wdDsgb3B0ID0gc3RydG9rKE5VTEwsICIsIikpIHsKCQljaGFyICpvcHRlcSA9IHN0cmNocihvcHQsICc9Jyk7CgkJaWYgKG9wdGVxKSB7CgkJCXN0YXRpYyBjb25zdCBjaGFyIG9wdGlvbnNbXSBBTElHTjEgPQoJCQkJLyogMCAqLyAicnNpemVcMCIKCQkJCS8qIDEgKi8gIndzaXplXDAiCgkJCQkvKiAyICovICJ0aW1lb1wwIgoJCQkJLyogMyAqLyAicmV0cmFuc1wwIgoJCQkJLyogNCAqLyAiYWNyZWdtaW5cMCIKCQkJCS8qIDUgKi8gImFjcmVnbWF4XDAiCgkJCQkvKiA2ICovICJhY2Rpcm1pblwwIgoJCQkJLyogNyAqLyAiYWNkaXJtYXhcMCIKCQkJCS8qIDggKi8gImFjdGltZW9cMCIKCQkJCS8qIDkgKi8gInJldHJ5XDAiCgkJCQkvKiAxMCAqLyAicG9ydFwwIgoJCQkJLyogMTEgKi8gIm1vdW50cG9ydFwwIgoJCQkJLyogMTIgKi8gIm1vdW50aG9zdFwwIgoJCQkJLyogMTMgKi8gIm1vdW50cHJvZ1wwIgoJCQkJLyogMTQgKi8gIm1vdW50dmVyc1wwIgoJCQkJLyogMTUgKi8gIm5mc3Byb2dcMCIKCQkJCS8qIDE2ICovICJuZnN2ZXJzXDAiCgkJCQkvKiAxNyAqLyAidmVyc1wwIgoJCQkJLyogMTggKi8gInByb3RvXDAiCgkJCQkvKiAxOSAqLyAibmFtbGVuXDAiCgkJCQkvKiAyMCAqLyAiYWRkclwwIjsKCQkJaW50IHZhbCA9IHhhdG9pX3Uob3B0ZXEgKyAxKTsKCQkJKm9wdGVxID0gJ1wwJzsKCQkJc3dpdGNoIChpbmRleF9pbl9zdHJpbmdzKG9wdGlvbnMsIG9wdCkpIHsKCQkJY2FzZSAwOiAvLyAicnNpemUiCgkJCQlkYXRhLnJzaXplID0gdmFsOwoJCQkJYnJlYWs7CgkJCWNhc2UgMTogLy8gIndzaXplIgoJCQkJZGF0YS53c2l6ZSA9IHZhbDsKCQkJCWJyZWFrOwoJCQljYXNlIDI6IC8vICJ0aW1lbyIKCQkJCWRhdGEudGltZW8gPSB2YWw7CgkJCQlicmVhazsKCQkJY2FzZSAzOiAvLyAicmV0cmFucyIKCQkJCWRhdGEucmV0cmFucyA9IHZhbDsKCQkJCWJyZWFrOwoJCQljYXNlIDQ6IC8vICJhY3JlZ21pbiIKCQkJCWRhdGEuYWNyZWdtaW4gPSB2YWw7CgkJCQlicmVhazsKCQkJY2FzZSA1OiAvLyAiYWNyZWdtYXgiCgkJCQlkYXRhLmFjcmVnbWF4ID0gdmFsOwoJCQkJYnJlYWs7CgkJCWNhc2UgNjogLy8gImFjZGlybWluIgoJCQkJZGF0YS5hY2Rpcm1pbiA9IHZhbDsKCQkJCWJyZWFrOwoJCQljYXNlIDc6IC8vICJhY2Rpcm1heCIKCQkJCWRhdGEuYWNkaXJtYXggPSB2YWw7CgkJCQlicmVhazsKCQkJY2FzZSA4OiAvLyAiYWN0aW1lbyIKCQkJCWRhdGEuYWNyZWdtaW4gPSB2YWw7CgkJCQlkYXRhLmFjcmVnbWF4ID0gdmFsOwoJCQkJZGF0YS5hY2Rpcm1pbiA9IHZhbDsKCQkJCWRhdGEuYWNkaXJtYXggPSB2YWw7CgkJCQlicmVhazsKCQkJY2FzZSA5OiAvLyAicmV0cnkiCgkJCQlyZXRyeSA9IHZhbDsKCQkJCWJyZWFrOwoJCQljYXNlIDEwOiAvLyAicG9ydCIKCQkJCXBvcnQgPSB2YWw7CgkJCQlicmVhazsKCQkJY2FzZSAxMTogLy8gIm1vdW50cG9ydCIKCQkJCW1vdW50cG9ydCA9IHZhbDsKCQkJCWJyZWFrOwoJCQljYXNlIDEyOiAvLyAibW91bnRob3N0IgoJCQkJbW91bnRob3N0ID0geHN0cm5kdXAob3B0ZXErMSwKCQkJCQkJc3RyY3NwbihvcHRlcSsxLCIgXHRcblxyLCIpKTsKCQkJCWJyZWFrOwoJCQljYXNlIDEzOiAvLyAibW91bnRwcm9nIgoJCQkJbW91bnRwcm9nID0gdmFsOwoJCQkJYnJlYWs7CgkJCWNhc2UgMTQ6IC8vICJtb3VudHZlcnMiCgkJCQltb3VudHZlcnMgPSB2YWw7CgkJCQlicmVhazsKCQkJY2FzZSAxNTogLy8gIm5mc3Byb2ciCgkJCQluZnNwcm9nID0gdmFsOwoJCQkJYnJlYWs7CgkJCWNhc2UgMTY6IC8vICJuZnN2ZXJzIgoJCQljYXNlIDE3OiAvLyAidmVycyIKCQkJCW5mc3ZlcnMgPSB2YWw7CgkJCQlicmVhazsKCQkJY2FzZSAxODogLy8gInByb3RvIgoJCQkJaWYgKCFzdHJuY21wKG9wdGVxKzEsICJ0Y3AiLCAzKSkKCQkJCQl0Y3AgPSAxOwoJCQkJZWxzZSBpZiAoIXN0cm5jbXAob3B0ZXErMSwgInVkcCIsIDMpKQoJCQkJCXRjcCA9IDA7CgkJCQllbHNlCgkJCQkJYmJfZXJyb3JfbXNnKCJ3YXJuaW5nOiB1bnJlY29nbml6ZWQgcHJvdG89IG9wdGlvbiIpOwoJCQkJYnJlYWs7CgkJCWNhc2UgMTk6IC8vICJuYW1sZW4iCgkJCQlpZiAobmZzX21vdW50X3ZlcnNpb24gPj0gMikKCQkJCQlkYXRhLm5hbWxlbiA9IHZhbDsKCQkJCWVsc2UKCQkJCQliYl9lcnJvcl9tc2coIndhcm5pbmc6IG9wdGlvbiBuYW1sZW4gaXMgbm90IHN1cHBvcnRlZFxuIik7CgkJCQlicmVhazsKCQkJY2FzZSAyMDogLy8gImFkZHIiIC0gaWdub3JlCgkJCQlicmVhazsKCQkJZGVmYXVsdDoKCQkJCWJiX2Vycm9yX21zZygidW5rbm93biBuZnMgbW91bnQgcGFyYW1ldGVyOiAlcz0lZCIsIG9wdCwgdmFsKTsKCQkJCWdvdG8gZmFpbDsKCQkJfQoJCX0KCQllbHNlIHsKCQkJc3RhdGljIGNvbnN0IGNoYXIgb3B0aW9uc1tdIEFMSUdOMSA9CgkJCQkiYmdcMCIKCQkJCSJmZ1wwIgoJCQkJInNvZnRcMCIKCQkJCSJoYXJkXDAiCgkJCQkiaW50clwwIgoJCQkJInBvc2l4XDAiCgkJCQkiY3RvXDAiCgkJCQkiYWNcMCIKCQkJCSJ0Y3BcMCIKCQkJCSJ1ZHBcMCIKCQkJCSJsb2NrXDAiOwoJCQlpbnQgdmFsID0gMTsKCQkJaWYgKCFzdHJuY21wKG9wdCwgIm5vIiwgMikpIHsKCQkJCXZhbCA9IDA7CgkJCQlvcHQgKz0gMjsKCQkJfQoJCQlzd2l0Y2ggKGluZGV4X2luX3N0cmluZ3Mob3B0aW9ucywgb3B0KSkgewoJCQljYXNlIDA6IC8vICJiZyIKI2lmIEJCX01NVQoJCQkJYmcgPSB2YWw7CiNlbmRpZgoJCQkJYnJlYWs7CgkJCWNhc2UgMTogLy8gImZnIgojaWYgQkJfTU1VCgkJCQliZyA9ICF2YWw7CiNlbmRpZgoJCQkJYnJlYWs7CgkJCWNhc2UgMjogLy8gInNvZnQiCgkJCQlzb2Z0ID0gdmFsOwoJCQkJYnJlYWs7CgkJCWNhc2UgMzogLy8gImhhcmQiCgkJCQlzb2Z0ID0gIXZhbDsKCQkJCWJyZWFrOwoJCQljYXNlIDQ6IC8vICJpbnRyIgoJCQkJaW50ciA9IHZhbDsKCQkJCWJyZWFrOwoJCQljYXNlIDU6IC8vICJwb3NpeCIKCQkJCXBvc2l4ID0gdmFsOwoJCQkJYnJlYWs7CgkJCWNhc2UgNjogLy8gImN0byIKCQkJCW5vY3RvID0gIXZhbDsKCQkJCWJyZWFrOwoJCQljYXNlIDc6IC8vICJhYyIKCQkJCW5vYWMgPSAhdmFsOwoJCQkJYnJlYWs7CgkJCWNhc2UgODogLy8gInRjcCIKCQkJCXRjcCA9IHZhbDsKCQkJCWJyZWFrOwoJCQljYXNlIDk6IC8vICJ1ZHAiCgkJCQl0Y3AgPSAhdmFsOwoJCQkJYnJlYWs7CgkJCWNhc2UgMTA6IC8vICJsb2NrIgoJCQkJaWYgKG5mc19tb3VudF92ZXJzaW9uID49IDMpCgkJCQkJbm9sb2NrID0gIXZhbDsKCQkJCWVsc2UKCQkJCQliYl9lcnJvcl9tc2coIndhcm5pbmc6IG9wdGlvbiBub2xvY2sgaXMgbm90IHN1cHBvcnRlZCIpOwoJCQkJYnJlYWs7CgkJCWRlZmF1bHQ6CgkJCQliYl9lcnJvcl9tc2coInVua25vd24gbmZzIG1vdW50IG9wdGlvbjogJXMlcyIsIHZhbCA/ICIiIDogIm5vIiwgb3B0KTsKCQkJCWdvdG8gZmFpbDsKCQkJfQoJCX0KCX0KCXByb3RvID0gKHRjcCkgPyBJUFBST1RPX1RDUCA6IElQUFJPVE9fVURQOwoKCWRhdGEuZmxhZ3MgPSAoc29mdCA/IE5GU19NT1VOVF9TT0ZUIDogMCkKCQl8IChpbnRyID8gTkZTX01PVU5UX0lOVFIgOiAwKQoJCXwgKHBvc2l4ID8gTkZTX01PVU5UX1BPU0lYIDogMCkKCQl8IChub2N0byA/IE5GU19NT1VOVF9OT0NUTyA6IDApCgkJfCAobm9hYyA/IE5GU19NT1VOVF9OT0FDIDogMCk7CglpZiAobmZzX21vdW50X3ZlcnNpb24gPj0gMikKCQlkYXRhLmZsYWdzIHw9ICh0Y3AgPyBORlNfTU9VTlRfVENQIDogMCk7CglpZiAobmZzX21vdW50X3ZlcnNpb24gPj0gMykKCQlkYXRhLmZsYWdzIHw9IChub2xvY2sgPyBORlNfTU9VTlRfTk9OTE0gOiAwKTsKCWlmIChuZnN2ZXJzID4gTUFYX05GU1BST1QgfHwgbW91bnR2ZXJzID4gTUFYX05GU1BST1QpIHsKCQliYl9lcnJvcl9tc2coIk5GU3YlZCBub3Qgc3VwcG9ydGVkIiwgbmZzdmVycyk7CgkJZ290byBmYWlsOwoJfQoJaWYgKG5mc3ZlcnMgJiYgIW1vdW50dmVycykKCQltb3VudHZlcnMgPSAobmZzdmVycyA8IDMpID8gMSA6IG5mc3ZlcnM7CglpZiAobmZzdmVycyAmJiBuZnN2ZXJzIDwgbW91bnR2ZXJzKSB7CgkJbW91bnR2ZXJzID0gbmZzdmVyczsKCX0KCgkvKiBBZGp1c3Qgb3B0aW9ucyBpZiBub25lIHNwZWNpZmllZCAqLwoJaWYgKCFkYXRhLnRpbWVvKQoJCWRhdGEudGltZW8gPSB0Y3AgPyA3MCA6IDc7CgoJZGF0YS52ZXJzaW9uID0gbmZzX21vdW50X3ZlcnNpb247CgoJaWYgKHZmc2ZsYWdzICYgTVNfUkVNT1VOVCkKCQlnb3RvIGRvX21vdW50OwoKCS8qCgkgKiBJZiB0aGUgcHJldmlvdXMgbW91bnQgb3BlcmF0aW9uIG9uIHRoZSBzYW1lIGhvc3Qgd2FzCgkgKiBiYWNrZ3JvdW5kZWQsIGFuZCB0aGUgImJnIiBmb3IgdGhpcyBtb3VudCBpcyBhbHNvIHNldCwKCSAqIGdpdmUgdXAgaW1tZWRpYXRlbHksIHRvIGF2b2lkIHRoZSBpbml0aWFsIHRpbWVvdXQuCgkgKi8KCWlmIChiZyAmJiB3ZV9zYXdfdGhpc19ob3N0X2JlZm9yZShob3N0bmFtZSkpIHsKCQlkYWVtb25pemVkID0gZGFlbW9uaXplKCk7CgkJaWYgKGRhZW1vbml6ZWQgPD0gMCkgeyAvKiBwYXJlbnQgb3IgZXJyb3IgKi8KCQkJcmV0dmFsID0gLWRhZW1vbml6ZWQ7CgkJCWdvdG8gcmV0OwoJCX0KCX0KCgkvKiBjcmVhdGUgbW91bnQgZGFlbW9uIGNsaWVudCAqLwoJLyogU2VlIGlmIHRoZSBuZnMgaG9zdCA9IG1vdW50IGhvc3QuICovCglpZiAobW91bnRob3N0KSB7CgkJaWYgKG1vdW50aG9zdFswXSA+PSAnMCcgJiYgbW91bnRob3N0WzBdIDw9ICc5JykgewoJCQltb3VudF9zZXJ2ZXJfYWRkci5zaW5fZmFtaWx5ID0gQUZfSU5FVDsKCQkJbW91bnRfc2VydmVyX2FkZHIuc2luX2FkZHIuc19hZGRyID0gaW5ldF9hZGRyKGhvc3RuYW1lKTsKCQl9IGVsc2UgewoJCQlocCA9IGdldGhvc3RieW5hbWUobW91bnRob3N0KTsKCQkJaWYgKGhwID09IE5VTEwpIHsKCQkJCWJiX2hlcnJvcl9tc2coIiVzIiwgbW91bnRob3N0KTsKCQkJCWdvdG8gZmFpbDsKCQkJfSBlbHNlIHsKCQkJCWlmIChocC0+aF9sZW5ndGggPiBzaXplb2Yoc3RydWN0IGluX2FkZHIpKSB7CgkJCQkJYmJfZXJyb3JfbXNnKCJnb3QgYmFkIGhwLT5oX2xlbmd0aD8iKTsKCQkJCQlocC0+aF9sZW5ndGggPSBzaXplb2Yoc3RydWN0IGluX2FkZHIpOwoJCQkJfQoJCQkJbW91bnRfc2VydmVyX2FkZHIuc2luX2ZhbWlseSA9IEFGX0lORVQ7CgkJCQltZW1jcHkoJm1vdW50X3NlcnZlcl9hZGRyLnNpbl9hZGRyLAoJCQkJCQlocC0+aF9hZGRyLCBocC0+aF9sZW5ndGgpOwoJCQl9CgkJfQoJfQoKCS8qCgkgKiBUaGUgZm9sbG93aW5nIGxvb3AgaW1wbGVtZW50cyB0aGUgbW91bnQgcmV0cmllcy4gV2hlbiB0aGUgbW91bnQKCSAqIHRpbWVzIG91dCwgYW5kIHRoZSAiYmciIG9wdGlvbiBpcyBzZXQsIHdlIGJhY2tncm91bmQgb3Vyc2VsZgoJICogYW5kIGNvbnRpbnVlIHRyeWluZy4KCSAqCgkgKiBUaGUgY2FzZSB3aGVyZSB0aGUgbW91bnQgcG9pbnQgaXMgbm90IHByZXNlbnQgYW5kIHRoZSAiYmciCgkgKiBvcHRpb24gaXMgc2V0LCBpcyB0cmVhdGVkIGFzIGEgdGltZW91dC4gVGhpcyBpcyBkb25lIHRvCgkgKiBzdXBwb3J0IG5lc3RlZCBtb3VudHMuCgkgKgoJICogVGhlICJyZXRyeSIgY291bnQgc3BlY2lmaWVkIGJ5IHRoZSB1c2VyIGlzIHRoZSBudW1iZXIgb2YKCSAqIG1pbnV0ZXMgdG8gcmV0cnkgYmVmb3JlIGdpdmluZyB1cC4KCSAqLwoJewoJCXN0cnVjdCB0aW1ldmFsIHRvdGFsX3RpbWVvdXQ7CgkJc3RydWN0IHRpbWV2YWwgcmV0cnlfdGltZW91dDsKCQlzdHJ1Y3QgcG1hcCogcG1fbW50OwoJCXRpbWVfdCB0OwoJCXRpbWVfdCBwcmV2dDsKCQl0aW1lX3QgdGltZW91dDsKCgkJcmV0cnlfdGltZW91dC50dl9zZWMgPSAzOwoJCXJldHJ5X3RpbWVvdXQudHZfdXNlYyA9IDA7CgkJdG90YWxfdGltZW91dC50dl9zZWMgPSAyMDsKCQl0b3RhbF90aW1lb3V0LnR2X3VzZWMgPSAwOwoJCXRpbWVvdXQgPSB0aW1lKE5VTEwpICsgNjAgKiByZXRyeTsKCQlwcmV2dCA9IDA7CgkJdCA9IDMwOwpyZXRyeToKCQkvKiBiZSBjYXJlZnVsIG5vdCB0byB1c2UgdG9vIG1hbnkgQ1BVIGN5Y2xlcyAqLwoJCWlmICh0IC0gcHJldnQgPCAzMCkKCQkJc2xlZXAoMzApOwoKCQlwbV9tbnQgPSBnZXRfbW91bnRwb3J0KCZtb3VudF9zZXJ2ZXJfYWRkciwKCQkJCW1vdW50cHJvZywKCQkJCW1vdW50dmVycywKCQkJCXByb3RvLAoJCQkJbW91bnRwb3J0KTsKCQluZnN2ZXJzID0gKHBtX21udC0+cG1fdmVycyA8IDIpID8gMiA6IHBtX21udC0+cG1fdmVyczsKCgkJLyogY29udGFjdCB0aGUgbW91bnQgZGFlbW9uIHZpYSBUQ1AgKi8KCQltb3VudF9zZXJ2ZXJfYWRkci5zaW5fcG9ydCA9IGh0b25zKHBtX21udC0+cG1fcG9ydCk7CgkJbXNvY2sgPSBSUENfQU5ZU09DSzsKCgkJc3dpdGNoIChwbV9tbnQtPnBtX3Byb3QpIHsKCQljYXNlIElQUFJPVE9fVURQOgoJCQltY2xpZW50ID0gY2xudHVkcF9jcmVhdGUoJm1vdW50X3NlcnZlcl9hZGRyLAoJCQkJCQkgcG1fbW50LT5wbV9wcm9nLAoJCQkJCQkgcG1fbW50LT5wbV92ZXJzLAoJCQkJCQkgcmV0cnlfdGltZW91dCwKCQkJCQkJICZtc29jayk7CgkJCWlmIChtY2xpZW50KQoJCQkJYnJlYWs7CgkJCW1vdW50X3NlcnZlcl9hZGRyLnNpbl9wb3J0ID0gaHRvbnMocG1fbW50LT5wbV9wb3J0KTsKCQkJbXNvY2sgPSBSUENfQU5ZU09DSzsKCQljYXNlIElQUFJPVE9fVENQOgoJCQltY2xpZW50ID0gY2xudHRjcF9jcmVhdGUoJm1vdW50X3NlcnZlcl9hZGRyLAoJCQkJCQkgcG1fbW50LT5wbV9wcm9nLAoJCQkJCQkgcG1fbW50LT5wbV92ZXJzLAoJCQkJCQkgJm1zb2NrLCAwLCAwKTsKCQkJYnJlYWs7CgkJZGVmYXVsdDoKCQkJbWNsaWVudCA9IE5VTEw7CgkJfQoJCWlmICghbWNsaWVudCkgewoJCQlpZiAoIWRhZW1vbml6ZWQgJiYgcHJldnQgPT0gMCkKCQkJCWVycm9yX21zZ19ycGMoY2xudF9zcGNyZWF0ZWVycm9yKCIgIikpOwoJCX0gZWxzZSB7CgkJCWVudW0gY2xudF9zdGF0IGNsbnRfc3RhdDsKCQkJLyogdHJ5IHRvIG1vdW50IGhvc3RuYW1lOnBhdGhuYW1lICovCgkJCW1jbGllbnQtPmNsX2F1dGggPSBhdXRodW5peF9jcmVhdGVfZGVmYXVsdCgpOwoKCQkJLyogbWFrZSBwb2ludGVycyBpbiB4ZHJfbW91bnRyZXMzIE5VTEwgc28KCQkJICogdGhhdCB4ZHJfYXJyYXkgYWxsb2NhdGVzIG1lbW9yeSBmb3IgdXMKCQkJICovCgkJCW1lbXNldCgmc3RhdHVzLCAwLCBzaXplb2Yoc3RhdHVzKSk7CgoJCQlpZiAocG1fbW50LT5wbV92ZXJzID09IDMpCgkJCQljbG50X3N0YXQgPSBjbG50X2NhbGwobWNsaWVudCwgTU9VTlRQUk9DM19NTlQsCgkJCQkJICAgICAgKHhkcnByb2NfdCkgeGRyX2RpcnBhdGgsCgkJCQkJICAgICAgKGNhZGRyX3QpICZwYXRobmFtZSwKCQkJCQkgICAgICAoeGRycHJvY190KSB4ZHJfbW91bnRyZXMzLAoJCQkJCSAgICAgIChjYWRkcl90KSAmc3RhdHVzLAoJCQkJCSAgICAgIHRvdGFsX3RpbWVvdXQpOwoJCQllbHNlCgkJCQljbG50X3N0YXQgPSBjbG50X2NhbGwobWNsaWVudCwgTU9VTlRQUk9DX01OVCwKCQkJCQkgICAgICAoeGRycHJvY190KSB4ZHJfZGlycGF0aCwKCQkJCQkgICAgICAoY2FkZHJfdCkgJnBhdGhuYW1lLAoJCQkJCSAgICAgICh4ZHJwcm9jX3QpIHhkcl9maHN0YXR1cywKCQkJCQkgICAgICAoY2FkZHJfdCkgJnN0YXR1cywKCQkJCQkgICAgICB0b3RhbF90aW1lb3V0KTsKCgkJCWlmIChjbG50X3N0YXQgPT0gUlBDX1NVQ0NFU1MpCgkJCQlnb3RvIHByZXBhcmVfa2VybmVsX2RhdGE7IC8qIHdlJ3JlIGRvbmUgKi8KCQkJaWYgKGVycm5vICE9IEVDT05OUkVGVVNFRCkgewoJCQkJZXJyb3JfbXNnX3JwYyhjbG50X3NwZXJyb3IobWNsaWVudCwgIiAiKSk7CgkJCQlnb3RvIGZhaWw7CS8qIGRvbid0IHJldHJ5ICovCgkJCX0KCQkJLyogQ29ubmVjdGlvbiByZWZ1c2VkICovCgkJCWlmICghZGFlbW9uaXplZCAmJiBwcmV2dCA9PSAwKSAvKiBwcmludCBqdXN0IG9uY2UgKi8KCQkJCWVycm9yX21zZ19ycGMoY2xudF9zcGVycm9yKG1jbGllbnQsICIgIikpOwoJCQlhdXRoX2Rlc3Ryb3kobWNsaWVudC0+Y2xfYXV0aCk7CgkJCWNsbnRfZGVzdHJveShtY2xpZW50KTsKCQkJbWNsaWVudCA9IE5VTEw7CgkJCWNsb3NlKG1zb2NrKTsKCQkJbXNvY2sgPSAtMTsKCQl9CgoJCS8qIFRpbWVvdXQuIFdlIGFyZSBnb2luZyB0byByZXRyeS4uLiBtYXliZSAqLwoKCQlpZiAoIWJnKQoJCQlnb3RvIGZhaWw7CgkJaWYgKCFkYWVtb25pemVkKSB7CgkJCWRhZW1vbml6ZWQgPSBkYWVtb25pemUoKTsKCQkJaWYgKGRhZW1vbml6ZWQgPD0gMCkgeyAvKiBwYXJlbnQgb3IgZXJyb3IgKi8KCQkJCXJldHZhbCA9IC1kYWVtb25pemVkOwoJCQkJZ290byByZXQ7CgkJCX0KCQl9CgkJcHJldnQgPSB0OwoJCXQgPSB0aW1lKE5VTEwpOwoJCWlmICh0ID49IHRpbWVvdXQpCgkJCS8qIFRPRE8gZXJyb3IgbWVzc2FnZSAqLwoJCQlnb3RvIGZhaWw7CgoJCWdvdG8gcmV0cnk7Cgl9CgpwcmVwYXJlX2tlcm5lbF9kYXRhOgoKCWlmIChuZnN2ZXJzID09IDIpIHsKCQlpZiAoc3RhdHVzLm5mc3YyLmZoc19zdGF0dXMgIT0gMCkgewoJCQliYl9lcnJvcl9tc2coIiVzOiVzIGZhaWxlZCwgcmVhc29uIGdpdmVuIGJ5IHNlcnZlcjogJXMiLAoJCQkJaG9zdG5hbWUsIHBhdGhuYW1lLAoJCQkJbmZzX3N0cmVycm9yKHN0YXR1cy5uZnN2Mi5maHNfc3RhdHVzKSk7CgkJCWdvdG8gZmFpbDsKCQl9CgkJbWVtY3B5KGRhdGEucm9vdC5kYXRhLAoJCQkJKGNoYXIgKikgc3RhdHVzLm5mc3YyLmZoc3RhdHVzX3UuZmhzX2ZoYW5kbGUsCgkJCQlORlNfRkhTSVpFKTsKCQlkYXRhLnJvb3Quc2l6ZSA9IE5GU19GSFNJWkU7CgkJbWVtY3B5KGRhdGEub2xkX3Jvb3QuZGF0YSwKCQkJCShjaGFyICopIHN0YXR1cy5uZnN2Mi5maHN0YXR1c191LmZoc19maGFuZGxlLAoJCQkJTkZTX0ZIU0laRSk7Cgl9IGVsc2UgewoJCWZoYW5kbGUzICpteV9maGFuZGxlOwoJCWlmIChzdGF0dXMubmZzdjMuZmhzX3N0YXR1cyAhPSAwKSB7CgkJCWJiX2Vycm9yX21zZygiJXM6JXMgZmFpbGVkLCByZWFzb24gZ2l2ZW4gYnkgc2VydmVyOiAlcyIsCgkJCQlob3N0bmFtZSwgcGF0aG5hbWUsCgkJCQluZnNfc3RyZXJyb3Ioc3RhdHVzLm5mc3YzLmZoc19zdGF0dXMpKTsKCQkJZ290byBmYWlsOwoJCX0KCQlteV9maGFuZGxlID0gJnN0YXR1cy5uZnN2My5tb3VudHJlczNfdS5tb3VudGluZm8uZmhhbmRsZTsKCQltZW1zZXQoZGF0YS5vbGRfcm9vdC5kYXRhLCAwLCBORlNfRkhTSVpFKTsKCQltZW1zZXQoJmRhdGEucm9vdCwgMCwgc2l6ZW9mKGRhdGEucm9vdCkpOwoJCWRhdGEucm9vdC5zaXplID0gbXlfZmhhbmRsZS0+ZmhhbmRsZTNfbGVuOwoJCW1lbWNweShkYXRhLnJvb3QuZGF0YSwKCQkJCShjaGFyICopIG15X2ZoYW5kbGUtPmZoYW5kbGUzX3ZhbCwKCQkJCW15X2ZoYW5kbGUtPmZoYW5kbGUzX2xlbik7CgoJCWRhdGEuZmxhZ3MgfD0gTkZTX01PVU5UX1ZFUjM7Cgl9CgoJLyogY3JlYXRlIG5mcyBzb2NrZXQgZm9yIGtlcm5lbCAqLwoKCWlmICh0Y3ApIHsKCQlpZiAobmZzX21vdW50X3ZlcnNpb24gPCAzKSB7CgkJCWJiX2Vycm9yX21zZygiTkZTIG92ZXIgVENQIGlzIG5vdCBzdXBwb3J0ZWQiKTsKCQkJZ290byBmYWlsOwoJCX0KCQlmc29jayA9IHNvY2tldChBRl9JTkVULCBTT0NLX1NUUkVBTSwgSVBQUk9UT19UQ1ApOwoJfSBlbHNlCgkJZnNvY2sgPSBzb2NrZXQoQUZfSU5FVCwgU09DS19ER1JBTSwgSVBQUk9UT19VRFApOwoJaWYgKGZzb2NrIDwgMCkgewoJCWJiX3BlcnJvcl9tc2coIm5mcyBzb2NrZXQiKTsKCQlnb3RvIGZhaWw7Cgl9CglpZiAoYmluZHJlc3Zwb3J0KGZzb2NrLCAwKSA8IDApIHsKCQliYl9wZXJyb3JfbXNnKCJuZnMgYmluZHJlc3Zwb3J0Iik7CgkJZ290byBmYWlsOwoJfQoJaWYgKHBvcnQgPT0gMCkgewoJCXNlcnZlcl9hZGRyLnNpbl9wb3J0ID0gUE1BUFBPUlQ7CgkJcG9ydCA9IHBtYXBfZ2V0cG9ydCgmc2VydmVyX2FkZHIsIG5mc3Byb2csIG5mc3ZlcnMsCgkJCQkJdGNwID8gSVBQUk9UT19UQ1AgOiBJUFBST1RPX1VEUCk7CgkJaWYgKHBvcnQgPT0gMCkKCQkJcG9ydCA9IE5GU19QT1JUOwoJfQoJc2VydmVyX2FkZHIuc2luX3BvcnQgPSBodG9ucyhwb3J0KTsKCgkvKiBwcmVwYXJlIGRhdGEgc3RydWN0dXJlIGZvciBrZXJuZWwgKi8KCglkYXRhLmZkID0gZnNvY2s7CgltZW1jcHkoKGNoYXIgKikgJmRhdGEuYWRkciwgKGNoYXIgKikgJnNlcnZlcl9hZGRyLCBzaXplb2YoZGF0YS5hZGRyKSk7CglzdHJuY3B5KGRhdGEuaG9zdG5hbWUsIGhvc3RuYW1lLCBzaXplb2YoZGF0YS5ob3N0bmFtZSkpOwoKCS8qIGNsZWFuIHVwICovCgoJYXV0aF9kZXN0cm95KG1jbGllbnQtPmNsX2F1dGgpOwoJY2xudF9kZXN0cm95KG1jbGllbnQpOwoJY2xvc2UobXNvY2spOwoJbXNvY2sgPSAtMTsKCglpZiAoYmcpIHsKCQkvKiBXZSBtdXN0IHdhaXQgdW50aWwgbW91bnQgZGlyZWN0b3J5IGlzIGF2YWlsYWJsZSAqLwoJCXN0cnVjdCBzdGF0IHN0YXRidWY7CgkJaW50IGRlbGF5ID0gMTsKCQl3aGlsZSAoc3RhdChtcC0+bW50X2RpciwgJnN0YXRidWYpID09IC0xKSB7CgkJCWlmICghZGFlbW9uaXplZCkgewoJCQkJZGFlbW9uaXplZCA9IGRhZW1vbml6ZSgpOwoJCQkJaWYgKGRhZW1vbml6ZWQgPD0gMCkgeyAvKiBwYXJlbnQgb3IgZXJyb3IgKi8KCS8vIEZJWE1FOiBwYXJlbnQgZG9lc24ndCBjbG9zZSBmc29jayAtID8/IQoJCQkJCXJldHZhbCA9IC1kYWVtb25pemVkOwoJCQkJCWdvdG8gcmV0OwoJCQkJfQoJCQl9CgkJCXNsZWVwKGRlbGF5KTsJLyogMSwgMiwgNCwgOCwgMTYsIDMwLCAuLi4gKi8KCQkJZGVsYXkgKj0gMjsKCQkJaWYgKGRlbGF5ID4gMzApCgkJCQlkZWxheSA9IDMwOwoJCX0KCX0KCmRvX21vdW50OiAvKiBwZXJmb3JtIGFjdHVhbCBtb3VudCAqLwoKCW1wLT5tbnRfdHlwZSA9IChjaGFyKikibmZzIjsKCXJldHZhbCA9IG1vdW50X2l0X25vdyhtcCwgdmZzZmxhZ3MsIChjaGFyKikmZGF0YSk7Cglnb3RvIHJldDsKCmZhaWw6CS8qIGFib3J0ICovCgoJaWYgKG1zb2NrID49IDApIHsKCQlpZiAobWNsaWVudCkgewoJCQlhdXRoX2Rlc3Ryb3kobWNsaWVudC0+Y2xfYXV0aCk7CgkJCWNsbnRfZGVzdHJveShtY2xpZW50KTsKCQl9CgkJY2xvc2UobXNvY2spOwoJfQoJaWYgKGZzb2NrID49IDApCgkJY2xvc2UoZnNvY2spOwoKcmV0OgoJZnJlZShob3N0bmFtZSk7CglmcmVlKG1vdW50aG9zdCk7CglmcmVlKGZpbHRlcm9wdHMpOwoJcmV0dXJuIHJldHZhbDsKfQoKI2Vsc2UgLyogIUVOQUJMRV9GRUFUVVJFX01PVU5UX05GUyAqLwoKLyogTmV2ZXIgY2FsbGVkLiBDYWxsIHNob3VsZCBiZSBvcHRpbWl6ZWQgb3V0LiAqLwppbnQgbmZzbW91bnQoc3RydWN0IG1udGVudCAqbXAsIGludCB2ZnNmbGFncywgY2hhciAqZmlsdGVyb3B0cyk7CgojZW5kaWYgLyogIUVOQUJMRV9GRUFUVVJFX01PVU5UX05GUyAqLwoKLy8gTW91bnQgb25lIGRpcmVjdG9yeS4gIEhhbmRsZXMgQ0lGUywgTkZTLCBsb29wYmFjaywgYXV0b2JpbmQsIGFuZCBmaWxlc3lzdGVtCi8vIHR5cGUgZGV0ZWN0aW9uLiAgUmV0dXJucyAwIGZvciBzdWNjZXNzLCBub256ZXJvIGZvciBmYWlsdXJlLgovLyBOQjogbXAtPnh4eCBmaWVsZHMgbWF5IGJlIHRyYXNoZWQgb24gZXhpdApzdGF0aWMgaW50IHNpbmdsZW1vdW50KHN0cnVjdCBtbnRlbnQgKm1wLCBpbnQgaWdub3JlX2J1c3kpCnsKCWludCByYyA9IC0xLCB2ZnNmbGFnczsKCWNoYXIgKmxvb3BGaWxlID0gMCwgKmZpbHRlcm9wdHMgPSAwOwoJbGxpc3RfdCAqZmwgPSAwOwoJc3RydWN0IHN0YXQgc3Q7CgoJdmZzZmxhZ3MgPSBwYXJzZV9tb3VudF9vcHRpb25zKG1wLT5tbnRfb3B0cywgJmZpbHRlcm9wdHMpOwoKCS8vIFRyZWF0IGZzdHlwZSAiYXV0byIgYXMgdW5zcGVjaWZpZWQuCgoJaWYgKG1wLT5tbnRfdHlwZSAmJiBzdHJjbXAobXAtPm1udF90eXBlLCJhdXRvIikgPT0gMCkKCQltcC0+bW50X3R5cGUgPSAwOwoKCS8vIE1pZ2h0IHRoaXMgYmUgYSB2aXJ0dWFsIGZpbGVzeXN0ZW0/CgoJaWYgKEVOQUJMRV9GRUFUVVJFX01PVU5UX0hFTFBFUlMKCSAmJiAoc3RyY2hyKG1wLT5tbnRfZnNuYW1lLCcjJykpCgkpIHsKCQljaGFyICpzLCAqcCwgKmFyZ3NbMzVdOwoJCWludCBuID0gMDsKCQlmb3IgKHMgPSBwID0gbXAtPm1udF9mc25hbWU7ICpzICYmIG4gPCAzNS0zOyArK3MpIHsKCQkJaWYgKHNbMF0gPT0gJyMnICYmIHNbMV0gIT0gJyMnKSB7CgkJCQkqcyA9ICdcMCc7CgkJCQlhcmdzW24rK10gPSBwOwoJCQkJcCA9IHMgKyAxOwoJCQl9CgkJfQoJCWFyZ3NbbisrXSA9IHA7CgkJYXJnc1tuKytdID0gbXAtPm1udF9kaXI7CgkJYXJnc1tuXSA9IE5VTEw7CgkJcmMgPSB3YWl0NHBpZCh4c3Bhd24oYXJncykpOwoJCWdvdG8gcmVwb3J0X2Vycm9yOwoJfQoKCS8vIE1pZ2h0IHRoaXMgYmUgYW4gQ0lGUyBmaWxlc3lzdGVtPwoKCWlmIChFTkFCTEVfRkVBVFVSRV9NT1VOVF9DSUZTCgkgJiYgKCFtcC0+bW50X3R5cGUgfHwgc3RyY21wKG1wLT5tbnRfdHlwZSwiY2lmcyIpID09IDApCgkgJiYgKG1wLT5tbnRfZnNuYW1lWzBdPT0nLycgfHwgbXAtPm1udF9mc25hbWVbMF09PSdcXCcpCgkgJiYgbXAtPm1udF9mc25hbWVbMF09PW1wLT5tbnRfZnNuYW1lWzFdCgkpIHsKCQlsZW5fYW5kX3NvY2thZGRyICpsc2E7CgkJY2hhciAqaXAsICpkb3R0ZWQ7CgkJY2hhciAqczsKCgkJcmMgPSAxOwoJCS8vIFJlcGxhY2UgJy8nIHdpdGggJ1wnIGFuZCB2ZXJpZnkgdGhhdCB1bmMgcG9pbnRzIHRvICIvL3NlcnZlci9zaGFyZSIuCgoJCWZvciAocyA9IG1wLT5tbnRfZnNuYW1lOyAqczsgKytzKQoJCQlpZiAoKnMgPT0gJy8nKSAqcyA9ICdcXCc7CgoJCS8vIGdldCBzZXJ2ZXIgSVAKCgkJcyA9IHN0cnJjaHIobXAtPm1udF9mc25hbWUsICdcXCcpOwoJCWlmIChzIDw9IG1wLT5tbnRfZnNuYW1lKzEpIGdvdG8gcmVwb3J0X2Vycm9yOwoJCSpzID0gJ1wwJzsKCQlsc2EgPSBob3N0MnNvY2thZGRyKG1wLT5tbnRfZnNuYW1lKzIsIDApOwoJCSpzID0gJ1xcJzsKCQlpZiAoIWxzYSkgZ290byByZXBvcnRfZXJyb3I7CgoJCS8vIGluc2VydCBpcD0uLi4gb3B0aW9uIGludG8gc3RyaW5nIGZsYWdzLgoKCQlkb3R0ZWQgPSB4bWFsbG9jX3NvY2thZGRyMmRvdHRlZF9ub3BvcnQoJmxzYS0+c2EpOwoJCWlwID0geGFzcHJpbnRmKCJpcD0lcyIsIGRvdHRlZCk7CgkJcGFyc2VfbW91bnRfb3B0aW9ucyhpcCwgJmZpbHRlcm9wdHMpOwoKCQkvLyBjb21wb3NlIG5ldyB1bmMgJ1xcc2VydmVyLWlwXHNoYXJlJwoJCS8vIChzID0+IHNsYXNoIGFmdGVyIGhvc3RuYW1lKQoKCQltcC0+bW50X2ZzbmFtZSA9IHhhc3ByaW50ZigiXFxcXCVzJXMiLCBkb3R0ZWQsIHMpOwoKCQkvLyBsb2NrIGlzIHJlcXVpcmVkCgkJdmZzZmxhZ3MgfD0gTVNfTUFORExPQ0s7CgoJCW1wLT5tbnRfdHlwZSA9IChjaGFyKikiY2lmcyI7CgkJcmMgPSBtb3VudF9pdF9ub3cobXAsIHZmc2ZsYWdzLCBmaWx0ZXJvcHRzKTsKCQlpZiAoRU5BQkxFX0ZFQVRVUkVfQ0xFQU5fVVApIHsKCQkJZnJlZShtcC0+bW50X2ZzbmFtZSk7CgkJCWZyZWUoaXApOwoJCQlmcmVlKGRvdHRlZCk7CgkJCWZyZWUobHNhKTsKCQl9CgkJZ290byByZXBvcnRfZXJyb3I7Cgl9CgoJLy8gTWlnaHQgdGhpcyBiZSBhbiBORlMgZmlsZXN5c3RlbT8KCglpZiAoRU5BQkxFX0ZFQVRVUkVfTU9VTlRfTkZTCgkgJiYgKCFtcC0+bW50X3R5cGUgfHwgIXN0cmNtcChtcC0+bW50X3R5cGUsICJuZnMiKSkKCSAmJiBzdHJjaHIobXAtPm1udF9mc25hbWUsICc6JykgIT0gTlVMTAoJKSB7CgkJcmMgPSBuZnNtb3VudChtcCwgdmZzZmxhZ3MsIGZpbHRlcm9wdHMpOwoJCWdvdG8gcmVwb3J0X2Vycm9yOwoJfQoKCS8vIExvb2sgYXQgdGhlIGZpbGUuICAoTm90IGZvdW5kIGlzbid0IGEgZmFpbHVyZSBmb3IgcmVtb3VudCwgb3IgZm9yCgkvLyBhIHN5bnRoZXRpYyBmaWxlc3lzdGVtIGxpa2UgcHJvYyBvciBzeXNmcy4pCgkvLyAoV2UgdXNlIHN0YXQsIG5vdCBsc3RhdCwgaW4gb3JkZXIgdG8gYWxsb3cKCS8vIG1vdW50IHN5bWxpbmtfdG9fZmlsZV9vcl9ibGtkZXYgZGlyKQoKCWlmICghc3RhdChtcC0+bW50X2ZzbmFtZSwgJnN0KQoJICYmICEodmZzZmxhZ3MgJiAoTVNfUkVNT1VOVCB8IE1TX0JJTkQgfCBNU19NT1ZFKSkKCSkgewoJCS8vIERvIHdlIG5lZWQgdG8gYWxsb2NhdGUgYSBsb29wYmFjayBkZXZpY2UgZm9yIGl0PwoKCQlpZiAoRU5BQkxFX0ZFQVRVUkVfTU9VTlRfTE9PUCAmJiBTX0lTUkVHKHN0LnN0X21vZGUpKSB7CgkJCWxvb3BGaWxlID0gYmJfc2ltcGxpZnlfcGF0aChtcC0+bW50X2ZzbmFtZSk7CgkJCW1wLT5tbnRfZnNuYW1lID0gTlVMTDsgLyogd2lsbCByZWNlaXZlIG1hbGxvY2VkIGxvb3AgZGV2IG5hbWUgKi8KCQkJaWYgKHNldF9sb29wKCYobXAtPm1udF9mc25hbWUpLCBsb29wRmlsZSwgMCkgPCAwKSB7CgkJCQlpZiAoZXJybm8gPT0gRVBFUk0gfHwgZXJybm8gPT0gRUFDQ0VTKQoJCQkJCWJiX2Vycm9yX21zZyhiYl9tc2dfcGVybV9kZW5pZWRfYXJlX3lvdV9yb290KTsKCQkJCWVsc2UKCQkJCQliYl9wZXJyb3JfbXNnKCJjYW5ub3Qgc2V0dXAgbG9vcCBkZXZpY2UiKTsKCQkJCXJldHVybiBlcnJubzsKCQkJfQoKCQkvLyBBdXRvZGV0ZWN0IGJpbmQgbW91bnRzCgoJCX0gZWxzZSBpZiAoU19JU0RJUihzdC5zdF9tb2RlKSAmJiAhbXAtPm1udF90eXBlKQoJCQl2ZnNmbGFncyB8PSBNU19CSU5EOwoJfQoKCS8qIElmIHdlIGtub3cgdGhlIGZzdHlwZSAob3IgZG9uJ3QgbmVlZCB0byksIGp1bXAgc3RyYWlnaHQKCSAqIHRvIHRoZSBhY3R1YWwgbW91bnQuICovCgoJaWYgKG1wLT5tbnRfdHlwZSB8fCAodmZzZmxhZ3MgJiAoTVNfUkVNT1VOVCB8IE1TX0JJTkQgfCBNU19NT1ZFKSkpCgkJcmMgPSBtb3VudF9pdF9ub3cobXAsIHZmc2ZsYWdzLCBmaWx0ZXJvcHRzKTsKCWVsc2UgewoJCS8vIExvb3AgdGhyb3VnaCBmaWxlc3lzdGVtIHR5cGVzIHVudGlsIG1vdW50IHN1Y2NlZWRzCgkJLy8gb3Igd2UgcnVuIG91dAoKCQkvKiBJbml0aWFsaXplIGxpc3Qgb2YgYmxvY2sgYmFja2VkIGZpbGVzeXN0ZW1zLiAgVGhpcyBoYXMgdG8gYmUKCQkgKiBkb25lIGhlcmUgc28gdGhhdCBkdXJpbmcgIm1vdW50IC1hIiwgbW91bnRzIGFmdGVyIC9wcm9jIHNob3dzIHVwCgkJICogY2FuIGF1dG9kZXRlY3QuICovCgoJCWlmICghZnNsaXN0KSB7CgkJCWZzbGlzdCA9IGdldF9ibG9ja19iYWNrZWRfZmlsZXN5c3RlbXMoKTsKCQkJaWYgKEVOQUJMRV9GRUFUVVJFX0NMRUFOX1VQICYmIGZzbGlzdCkKCQkJCWF0ZXhpdChkZWxldGVfYmxvY2tfYmFja2VkX2ZpbGVzeXN0ZW1zKTsKCQl9CgoJCWZvciAoZmwgPSBmc2xpc3Q7IGZsOyBmbCA9IGZsLT5saW5rKSB7CgkJCW1wLT5tbnRfdHlwZSA9IGZsLT5kYXRhOwoJCQlyYyA9IG1vdW50X2l0X25vdyhtcCwgdmZzZmxhZ3MsIGZpbHRlcm9wdHMpOwoJCQlpZiAoIXJjKSBicmVhazsKCQl9Cgl9CgoJLy8gSWYgbW91bnQgZmFpbGVkLCBjbGVhbiB1cCBsb29wIGZpbGUgKGlmIGFueSkuCgoJaWYgKEVOQUJMRV9GRUFUVVJFX01PVU5UX0xPT1AgJiYgcmMgJiYgbG9vcEZpbGUpIHsKCQlkZWxfbG9vcChtcC0+bW50X2ZzbmFtZSk7CgkJaWYgKEVOQUJMRV9GRUFUVVJFX0NMRUFOX1VQKSB7CgkJCWZyZWUobG9vcEZpbGUpOwoJCQlmcmVlKG1wLT5tbnRfZnNuYW1lKTsKCQl9Cgl9CgogcmVwb3J0X2Vycm9yOgoJaWYgKEVOQUJMRV9GRUFUVVJFX0NMRUFOX1VQKQoJCWZyZWUoZmlsdGVyb3B0cyk7CgoJaWYgKGVycm5vID09IEVCVVNZICYmIGlnbm9yZV9idXN5KQoJCXJldHVybiAwOwoJaWYgKHJjIDwgMCkKCQliYl9wZXJyb3JfbXNnKCJtb3VudGluZyAlcyBvbiAlcyBmYWlsZWQiLCBtcC0+bW50X2ZzbmFtZSwgbXAtPm1udF9kaXIpOwoJcmV0dXJuIHJjOwp9CgovLyBQYXJzZSBvcHRpb25zLCBpZiBuZWNlc3NhcnkgcGFyc2UgZnN0YWIvbXRhYiwgYW5kIGNhbGwgc2luZ2xlbW91bnQgZm9yCi8vIGVhY2ggZGlyZWN0b3J5IHRvIGJlIG1vdW50ZWQuCgpzdGF0aWMgY29uc3QgY2hhciBtdXN0X2JlX3Jvb3RbXSBBTElHTjEgPSAieW91IG11c3QgYmUgcm9vdCI7CgppbnQgbW91bnRfbWFpbihpbnQgYXJnYywgY2hhciAqKmFyZ3YpOwppbnQgbW91bnRfbWFpbihpbnQgYXJnYywgY2hhciAqKmFyZ3YpCnsKCWVudW0geyBPUFRfQUxMID0gMHgxMCB9OwoKCWNoYXIgKmNtZG9wdHMgPSB4c3RyZHVwKCIiKSwgKmZzdHlwZT0wLCAqc3RvcmFnZV9wYXRoPTA7CgljaGFyICpvcHRfbzsKCWNvbnN0IGNoYXIgKmZzdGFibmFtZTsKCUZJTEUgKmZzdGFiOwoJaW50IGksIGosIHJjID0gMDsKCXVuc2lnbmVkIG9wdDsKCXN0cnVjdCBtbnRlbnQgbXRwYWlyWzJdLCAqbXRjdXIgPSBtdHBhaXI7CglTS0lQX0RFU0tUT1AoY29uc3QgaW50IG5vbnJvb3QgPSAwOykKCVVTRV9ERVNLVE9QKCBpbnQgbm9ucm9vdCA9IChnZXR1aWQoKSAhPSAwKTspCgoJLyogcGFyc2UgbG9uZyBvcHRpb25zLCBsaWtlIC0tYmluZCBhbmQgLS1tb3ZlLiAgTm90ZSB0aGF0IC1vIG9wdGlvbgoJICogYW5kIC0tb3B0aW9uIGFyZSBzeW5vbnltb3VzLiAgWWVzLCB0aGlzIG1lYW5zIC0tcmVtb3VudCxydyB3b3Jrcy4gKi8KCglmb3IgKGkgPSBqID0gMDsgaSA8IGFyZ2M7IGkrKykgewoJCWlmIChhcmd2W2ldWzBdID09ICctJyAmJiBhcmd2W2ldWzFdID09ICctJykgewoJCQlhcHBlbmRfbW91bnRfb3B0aW9ucygmY21kb3B0cywgYXJndltpXSsyKTsKCQl9IGVsc2UgYXJndltqKytdID0gYXJndltpXTsKCX0KCWFyZ3Zbal0gPSAwOwoJYXJnYyA9IGo7CgoJLy8gUGFyc2UgcmVtYWluaW5nIG9wdGlvbnMKCglvcHQgPSBnZXRvcHQzMihhcmd2LCAibzp0OnJ3YW5mdnNpIiwgJm9wdF9vLCAmZnN0eXBlKTsKCWlmIChvcHQgJiAweDEpIGFwcGVuZF9tb3VudF9vcHRpb25zKCZjbWRvcHRzLCBvcHRfbyk7IC8vIC1vCgkvL2lmIChvcHQgJiAweDIpIC8vIC10CglpZiAob3B0ICYgMHg0KSBhcHBlbmRfbW91bnRfb3B0aW9ucygmY21kb3B0cywgInJvIik7IC8vIC1yCglpZiAob3B0ICYgMHg4KSBhcHBlbmRfbW91bnRfb3B0aW9ucygmY21kb3B0cywgInJ3Iik7IC8vIC13CgkvL2lmIChvcHQgJiAweDEwKSAvLyAtYQoJaWYgKG9wdCAmIDB4MjApIFVTRV9GRUFUVVJFX01UQUJfU1VQUE9SVCh1c2VNdGFiID0gMCk7IC8vIC1uCglpZiAob3B0ICYgMHg0MCkgVVNFX0ZFQVRVUkVfTVRBQl9TVVBQT1JUKGZha2VJdCA9IDEpOyAvLyAtZgoJLy9pZiAob3B0ICYgMHg4MCkgLy8gLXY6IHZlcmJvc2UgKGlnbm9yZSkKCS8vaWYgKG9wdCAmIDB4MTAwKSAvLyAtczogc2xvcHB5IChpZ25vcmUpCgkvL2lmIChvcHQgJiAweDIwMCkgLy8gLWk6IGRvbid0IGNhbGwgbW91bnQuPGZzdHlwZT4gKGlnbm9yZSkKCWFyZ3YgKz0gb3B0aW5kOwoJYXJnYyAtPSBvcHRpbmQ7CgoJLy8gVGhyZWUgb3IgbW9yZSBub24tb3B0aW9uIGFyZ3VtZW50cz8gIERpZSB3aXRoIGEgdXNhZ2UgbWVzc2FnZS4KCglpZiAoYXJnYyA+IDIpIGJiX3Nob3dfdXNhZ2UoKTsKCgkvLyBJZiB3ZSBoYXZlIG5vIGFyZ3VtZW50cywgc2hvdyBjdXJyZW50bHkgbW91bnRlZCBmaWxlc3lzdGVtcwoKCWlmICghYXJnYykgewoJCWlmICghKG9wdCAmIE9QVF9BTEwpKSB7CgkJCUZJTEUgKm1vdW50VGFibGUgPSBzZXRtbnRlbnQoYmJfcGF0aF9tdGFiX2ZpbGUsICJyIik7CgoJCQlpZiAoIW1vdW50VGFibGUpIGJiX2Vycm9yX21zZ19hbmRfZGllKCJubyAlcyIsIGJiX3BhdGhfbXRhYl9maWxlKTsKCgkJCXdoaWxlIChnZXRtbnRlbnRfcihtb3VudFRhYmxlLCAmbXRwYWlyWzBdLCBnZXRtbnRlbnRfYnVmLAoJCQkJCQkJCXNpemVvZihnZXRtbnRlbnRfYnVmKSkpCgkJCXsKCQkJCS8vIERvbid0IHNob3cgcm9vdGZzLiBGSVhNRTogd2h5Pz8KCQkJCS8vIHV0aWwtbGludXggMi4xMmEgaGFwcGlseSBzaG93cyByb290ZnMuLi4KCQkJCS8vaWYgKCFzdHJjbXAobXRwYWlyLT5tbnRfZnNuYW1lLCAicm9vdGZzIikpIGNvbnRpbnVlOwoKCQkJCWlmICghZnN0eXBlIHx8ICFzdHJjbXAobXRwYWlyLT5tbnRfdHlwZSwgZnN0eXBlKSkKCQkJCQlwcmludGYoIiVzIG9uICVzIHR5cGUgJXMgKCVzKVxuIiwgbXRwYWlyLT5tbnRfZnNuYW1lLAoJCQkJCQkJbXRwYWlyLT5tbnRfZGlyLCBtdHBhaXItPm1udF90eXBlLAoJCQkJCQkJbXRwYWlyLT5tbnRfb3B0cyk7CgkJCX0KCQkJaWYgKEVOQUJMRV9GRUFUVVJFX0NMRUFOX1VQKSBlbmRtbnRlbnQobW91bnRUYWJsZSk7CgkJCXJldHVybiBFWElUX1NVQ0NFU1M7CgkJfQoJfSBlbHNlIHN0b3JhZ2VfcGF0aCA9IGJiX3NpbXBsaWZ5X3BhdGgoYXJndlswXSk7CgoJLy8gV2hlbiB3ZSBoYXZlIHR3byBhcmd1bWVudHMsIHRoZSBzZWNvbmQgaXMgdGhlIGRpcmVjdG9yeSBhbmQgd2UgY2FuCgkvLyBza2lwIGxvb2tpbmcgYXQgZnN0YWIgZW50aXJlbHkuICBXZSBjYW4gYWx3YXlzIGFic3BhdGgoKSB0aGUgZGlyZWN0b3J5CgkvLyBhcmd1bWVudCB3aGVuIHdlIGdldCBpdC4KCglpZiAoYXJnYyA9PSAyKSB7CgkJaWYgKG5vbnJvb3QpCgkJCWJiX2Vycm9yX21zZ19hbmRfZGllKG11c3RfYmVfcm9vdCk7CgkJbXRwYWlyLT5tbnRfZnNuYW1lID0gYXJndlswXTsKCQltdHBhaXItPm1udF9kaXIgPSBhcmd2WzFdOwoJCW10cGFpci0+bW50X3R5cGUgPSBmc3R5cGU7CgkJbXRwYWlyLT5tbnRfb3B0cyA9IGNtZG9wdHM7CgkJcmMgPSBzaW5nbGVtb3VudChtdHBhaXIsIDApOwoJCWdvdG8gY2xlYW5fdXA7Cgl9CgoJaSA9IHBhcnNlX21vdW50X29wdGlvbnMoY21kb3B0cywgMCk7CglpZiAobm9ucm9vdCAmJiAoaSAmIH5NU19TSUxFTlQpKSAvLyBOb24tcm9vdCB1c2VycyBjYW5ub3Qgc3BlY2lmeSBmbGFncwoJCWJiX2Vycm9yX21zZ19hbmRfZGllKG11c3RfYmVfcm9vdCk7CgoJLy8gSWYgd2UgaGF2ZSBhIHNoYXJlZCBzdWJ0cmVlIGZsYWcsIGRvbid0IHdvcnJ5IGFib3V0IGZzdGFiIG9yIG10YWIuCgoJaWYgKEVOQUJMRV9GRUFUVVJFX01PVU5UX0ZMQUdTCgkgJiYgKGkgJiAoTVNfU0hBUkVEIHwgTVNfUFJJVkFURSB8IE1TX1NMQVZFIHwgTVNfVU5CSU5EQUJMRSkpCgkpIHsKCQlyYyA9IG1vdW50KCIiLCBhcmd2WzBdLCAiIiwgaSwgIiIpOwoJCWlmIChyYykgYmJfcGVycm9yX21zZ19hbmRfZGllKCIlcyIsIGFyZ3ZbMF0pOwoJCWdvdG8gY2xlYW5fdXA7Cgl9CgoJLy8gT3BlbiBlaXRoZXIgZnN0YWIgb3IgbXRhYgoKCWZzdGFibmFtZSA9ICIvZXRjL2ZzdGFiIjsKCWlmIChpICYgTVNfUkVNT1VOVCkgewoJCWZzdGFibmFtZSA9IGJiX3BhdGhfbXRhYl9maWxlOwoJfQoJZnN0YWIgPSBzZXRtbnRlbnQoZnN0YWJuYW1lLCAiciIpOwoJaWYgKCFmc3RhYikKCQliYl9wZXJyb3JfbXNnX2FuZF9kaWUoImNhbm5vdCByZWFkICVzIiwgZnN0YWJuYW1lKTsKCgkvLyBMb29wIHRocm91Z2ggZW50cmllcyB1bnRpbCB3ZSBmaW5kIHdoYXQgd2UncmUgbG9va2luZyBmb3IuCgoJbWVtc2V0KG10cGFpciwgMCwgc2l6ZW9mKG10cGFpcikpOwoJZm9yICg7OykgewoJCXN0cnVjdCBtbnRlbnQgKm10bmV4dCA9IChtdGN1cj09bXRwYWlyID8gbXRwYWlyKzEgOiBtdHBhaXIpOwoKCQkvLyBHZXQgbmV4dCBmc3RhYiBlbnRyeQoKCQlpZiAoIWdldG1udGVudF9yKGZzdGFiLCBtdGN1ciwgZ2V0bW50ZW50X2J1ZgoJCQkJCSsgKG10Y3VyPT1tdHBhaXIgPyBzaXplb2YoZ2V0bW50ZW50X2J1ZikvMiA6IDApLAoJCQkJc2l6ZW9mKGdldG1udGVudF9idWYpLzIpKQoJCXsKCQkJLy8gV2VyZSB3ZSBsb29raW5nIGZvciBzb21ldGhpbmcgc3BlY2lmaWM/CgoJCQlpZiAoYXJnYykgewoKCQkJCS8vIElmIHdlIGRpZG4ndCBmaW5kIGFueXRoaW5nLCBjb21wbGFpbi4KCgkJCQlpZiAoIW10bmV4dC0+bW50X2ZzbmFtZSkKCQkJCQliYl9lcnJvcl9tc2dfYW5kX2RpZSgiY2FuJ3QgZmluZCAlcyBpbiAlcyIsCgkJCQkJCWFyZ3ZbMF0sIGZzdGFibmFtZSk7CgoJCQkJbXRjdXIgPSBtdG5leHQ7CgkJCQlpZiAobm9ucm9vdCkgewoJCQkJCS8vIGZzdGFiIG11c3QgaGF2ZSAidXNlcnMiIG9yICJ1c2VyIgoJCQkJCWlmICghKHBhcnNlX21vdW50X29wdGlvbnMobXRjdXItPm1udF9vcHRzLCAwKSAmIE1PVU5UX1VTRVJTKSkKCQkJCQkJYmJfZXJyb3JfbXNnX2FuZF9kaWUobXVzdF9iZV9yb290KTsKCQkJCX0KCgkJCQkvLyBNb3VudCB0aGUgbGFzdCB0aGluZyB3ZSBmb3VuZC4KCgkJCQltdGN1ci0+bW50X29wdHMgPSB4c3RyZHVwKG10Y3VyLT5tbnRfb3B0cyk7CgkJCQlhcHBlbmRfbW91bnRfb3B0aW9ucygmKG10Y3VyLT5tbnRfb3B0cyksIGNtZG9wdHMpOwoJCQkJcmMgPSBzaW5nbGVtb3VudChtdGN1ciwgMCk7CgkJCQlmcmVlKG10Y3VyLT5tbnRfb3B0cyk7CgkJCX0KCQkJZ290byBjbGVhbl91cDsKCQl9CgoJCS8qIElmIHdlJ3JlIHRyeWluZyB0byBtb3VudCBzb21ldGhpbmcgc3BlY2lmaWMgYW5kIHRoaXMgaXNuJ3QgaXQsCgkJICogc2tpcCBpdC4gIE5vdGUgd2UgbXVzdCBtYXRjaCBib3RoIHRoZSBleGFjdCB0ZXh0IGluIGZzdGFiIChhbGEKCQkgKiAicHJvYyIpIG9yIGEgZnVsbCBwYXRoIGZyb20gcm9vdCAqLwoKCQlpZiAoYXJnYykgewoKCQkJLy8gSXMgdGhpcyB3aGF0IHdlJ3JlIGxvb2tpbmcgZm9yPwoKCQkJaWYgKHN0cmNtcChhcmd2WzBdLCBtdGN1ci0+bW50X2ZzbmFtZSkgJiYKCQkJICAgc3RyY21wKHN0b3JhZ2VfcGF0aCwgbXRjdXItPm1udF9mc25hbWUpICYmCgkJCSAgIHN0cmNtcChhcmd2WzBdLCBtdGN1ci0+bW50X2RpcikgJiYKCQkJICAgc3RyY21wKHN0b3JhZ2VfcGF0aCwgbXRjdXItPm1udF9kaXIpKSBjb250aW51ZTsKCgkJCS8vIFJlbWVtYmVyIHRoaXMgZW50cnkuICBTb21ldGhpbmcgbGF0ZXIgbWF5IGhhdmUgb3Zlcm1vdW50ZWQKCQkJLy8gaXQsIGFuZCB3ZSB3YW50IHRoZSBfbGFzdF8gbWF0Y2guCgoJCQltdGN1ciA9IG10bmV4dDsKCgkJLy8gSWYgd2UncmUgbW91bnRpbmcgYWxsLgoKCQl9IGVsc2UgewoJCQkvLyBEbyB3ZSBuZWVkIHRvIG1hdGNoIGEgZmlsZXN5c3RlbSB0eXBlPwoJCQlpZiAoZnN0eXBlICYmIG1hdGNoX2ZzdHlwZShtdGN1ciwgZnN0eXBlKSkgY29udGludWU7CgoJCQkvLyBTa2lwIG5vYXV0byBhbmQgc3dhcCBhbnl3YXkuCgoJCQlpZiAocGFyc2VfbW91bnRfb3B0aW9ucyhtdGN1ci0+bW50X29wdHMsIDApCgkJCQkmIChNT1VOVF9OT0FVVE8gfCBNT1VOVF9TV0FQKSkgY29udGludWU7CgoJCQkvLyBObywgbW91bnQgLWEgd29uJ3QgbW91bnQgYW55dGhpbmcsCgkJCS8vIGV2ZW4gdXNlciBtb3VudHMsIGZvciBtZXJlIGh1bWFucy4KCgkJCWlmIChub25yb290KQoJCQkJYmJfZXJyb3JfbXNnX2FuZF9kaWUobXVzdF9iZV9yb290KTsKCgkJCS8vIE1vdW50IHRoaXMgdGhpbmcuCgoJCQkvLyBORlMgbW91bnRzIHdhbnQgdGhpcyB0byBiZSB4cmVhbGxvYy1hYmxlCgkJCW10Y3VyLT5tbnRfb3B0cyA9IHhzdHJkdXAobXRjdXItPm1udF9vcHRzKTsKCQkJaWYgKHNpbmdsZW1vdW50KG10Y3VyLCAxKSkgewoJCQkJLyogQ291bnQgbnVtYmVyIG9mIGZhaWxlZCBtb3VudHMgKi8KCQkJCXJjKys7CgkJCX0KCQkJZnJlZShtdGN1ci0+bW50X29wdHMpOwoJCX0KCX0KCWlmIChFTkFCTEVfRkVBVFVSRV9DTEVBTl9VUCkgZW5kbW50ZW50KGZzdGFiKTsKCmNsZWFuX3VwOgoKCWlmIChFTkFCTEVfRkVBVFVSRV9DTEVBTl9VUCkgewoJCWZyZWUoc3RvcmFnZV9wYXRoKTsKCQlmcmVlKGNtZG9wdHMpOwoJfQoKCXJldHVybiByYzsKfQo=