Lyogdmk6IHNldCBzdz00IHRzPTQ6ICovCi8qCiAqIE1pbmkgbW91bnQgaW1wbGVtZW50YXRpb24gZm9yIGJ1c3lib3gKICoKICogQ29weXJpZ2h0IChDKSAxOTk1LCAxOTk2IGJ5IEJydWNlIFBlcmVucyA8YnJ1Y2VAcGl4YXIuY29tPi4KICogQ29weXJpZ2h0IChDKSAxOTk5LTIwMDQgYnkgRXJpayBBbmRlcnNlbiA8YW5kZXJzZW5AY29kZXBvZXQub3JnPgogKiBDb3B5cmlnaHQgKEMpIDIwMDUtMjAwNiBieSBSb2IgTGFuZGxleSA8cm9iQGxhbmRsZXkubmV0PgogKgogKiBMaWNlbnNlZCB1bmRlciBHUEx2MiBvciBsYXRlciwgc2VlIGZpbGUgTElDRU5TRSBpbiB0aGlzIHRhcmJhbGwgZm9yIGRldGFpbHMuCiAqLwoKLyogRGVzaWduIG5vdGVzOiBUaGVyZSBpcyBubyBzcGVjIGZvciBtb3VudC4gIFJlbWluZCBtZSB0byB3cml0ZSBvbmUuCgogICBtb3VudF9tYWluKCkgY2FsbHMgc2luZ2xlbW91bnQoKSB3aGljaCBjYWxscyBtb3VudF9pdF9ub3coKS4KCiAgIG1vdW50X21haW4oKSBjYW4gbG9vcCB0aHJvdWdoIC9ldGMvZnN0YWIgZm9yIG1vdW50IC1hCiAgIHNpbmdsZW1vdW50KCkgY2FuIGxvb3AgdGhyb3VnaCAvZXRjL2ZpbGVzeXN0ZW1zIGZvciBmc3R5cGUgZGV0ZWN0aW9uLgogICBtb3VudF9pdF9ub3coKSBkb2VzIHRoZSBhY3R1YWwgbW91bnQuCiovCgojaW5jbHVkZSAiYnVzeWJveC5oIgojaW5jbHVkZSA8bW50ZW50Lmg+CgovKiBOZWVkZWQgZm9yIG5mcyBzdXBwb3J0IG9ubHkuLi4gKi8KI2luY2x1ZGUgPHN5c2xvZy5oPgojaW5jbHVkZSA8c3lzL3V0c25hbWUuaD4KI3VuZGVmIFRSVUUKI3VuZGVmIEZBTFNFCiNpbmNsdWRlIDxycGMvcnBjLmg+CiNpbmNsdWRlIDxycGMvcG1hcF9wcm90Lmg+CiNpbmNsdWRlIDxycGMvcG1hcF9jbG50Lmg+CgoKLy8gTm90IHJlYWwgZmxhZ3MsIGJ1dCB3ZSB3YW50IHRvIGJlIGFibGUgdG8gY2hlY2sgZm9yIHRoaXMuCmVudW0gewoJTU9VTlRfVVNFUlMgID0gKDE8PDI4KSpFTkFCTEVfREVTS1RPUCwKCU1PVU5UX05PQVVUTyA9ICgxPDwyOSksCglNT1VOVF9TV0FQICAgPSAoMTw8MzApLAp9OwovLyBUT0RPOiBtb3JlICJ1c2VyIiBmbGFnIGNvbXBhdGliaWxpdHkuCi8vICJ1c2VyIiBvcHRpb24gKGZyb20gbW91bnQgbWFucGFnZSk6Ci8vIE9ubHkgdGhlIHVzZXIgdGhhdCBtb3VudGVkIGEgZmlsZXN5c3RlbSBjYW4gdW5tb3VudCBpdCBhZ2Fpbi4KLy8gSWYgYW55IHVzZXIgc2hvdWxkIGJlIGFibGUgdG8gdW5tb3VudCwgdGhlbiB1c2UgdXNlcnMgaW5zdGVhZCBvZiB1c2VyCi8vIGluIHRoZSBmc3RhYiBsaW5lLiAgVGhlIG93bmVyIG9wdGlvbiBpcyBzaW1pbGFyIHRvIHRoZSB1c2VyIG9wdGlvbiwKLy8gd2l0aCB0aGUgcmVzdHJpY3Rpb24gdGhhdCB0aGUgdXNlciBtdXN0IGJlIHRoZSBvd25lciBvZiB0aGUgc3BlY2lhbCBmaWxlLgovLyBUaGlzIG1heSBiZSB1c2VmdWwgZS5nLiBmb3IgL2Rldi9mZCBpZiBhIGxvZ2luIHNjcmlwdCBtYWtlcwovLyB0aGUgY29uc29sZSB1c2VyIG93bmVyIG9mIHRoaXMgZGV2aWNlLgoKLyogU3RhbmRhcmQgbW91bnQgb3B0aW9ucyAoZnJvbSAtbyBvcHRpb25zIG9yIC0tb3B0aW9ucyksIHdpdGggY29ycmVzcG9uZGluZwogKiBmbGFncyAqLwoKc3RydWN0IHsKCWNoYXIgKm5hbWU7Cglsb25nIGZsYWdzOwp9IHN0YXRpYyBtb3VudF9vcHRpb25zW10gPSB7CgkvLyBNU19GTEFHUyBzZXQgYSBiaXQuICB+TVNfRkxBR1MgZGlzYWJsZSB0aGF0IGJpdC4gIDAgZmxhZ3MgYXJlIE5PUHMuCgoJVVNFX0ZFQVRVUkVfTU9VTlRfTE9PUCgKCQl7Imxvb3AiLCAwfSwKCSkKCglVU0VfRkVBVFVSRV9NT1VOVF9GU1RBQigKCQl7ImRlZmF1bHRzIiwgMH0sCgkJLyogeyJxdWlldCIsIDB9LCAtIGRvIG5vdCBmaWx0ZXIgb3V0LCB2ZmF0IHdhbnRzIHRvIHNlZSBpdCAqLwoJCXsibm9hdXRvIiwgTU9VTlRfTk9BVVRPfSwKCQl7InN3YXAiLCBNT1VOVF9TV0FQfSwKCQlVU0VfREVTS1RPUCh7InVzZXIiLCAgTU9VTlRfVVNFUlN9LCkKCQlVU0VfREVTS1RPUCh7InVzZXJzIiwgTU9VTlRfVVNFUlN9LCkKCSkKCglVU0VfRkVBVFVSRV9NT1VOVF9GTEFHUygKCQkvLyB2ZnMgZmxhZ3MKCQl7Im5vc3VpZCIsIE1TX05PU1VJRH0sCgkJeyJzdWlkIiwgfk1TX05PU1VJRH0sCgkJeyJkZXYiLCB+TVNfTk9ERVZ9LAoJCXsibm9kZXYiLCBNU19OT0RFVn0sCgkJeyJleGVjIiwgfk1TX05PRVhFQ30sCgkJeyJub2V4ZWMiLCBNU19OT0VYRUN9LAoJCXsic3luYyIsIE1TX1NZTkNIUk9OT1VTfSwKCQl7ImFzeW5jIiwgfk1TX1NZTkNIUk9OT1VTfSwKCQl7ImF0aW1lIiwgfk1TX05PQVRJTUV9LAoJCXsibm9hdGltZSIsIE1TX05PQVRJTUV9LAoJCXsiZGlyYXRpbWUiLCB+TVNfTk9ESVJBVElNRX0sCgkJeyJub2RpcmF0aW1lIiwgTVNfTk9ESVJBVElNRX0sCgkJeyJsb3VkIiwgfk1TX1NJTEVOVH0sCgoJCS8vIGFjdGlvbiBmbGFncwoKCQl7ImJpbmQiLCBNU19CSU5EfSwKCQl7Im1vdmUiLCBNU19NT1ZFfSwKCQl7InNoYXJlZCIsIE1TX1NIQVJFRH0sCgkJeyJzbGF2ZSIsIE1TX1NMQVZFfSwKCQl7InByaXZhdGUiLCBNU19QUklWQVRFfSwKCQl7InVuYmluZGFibGUiLCBNU19VTkJJTkRBQkxFfSwKCQl7InJzaGFyZWQiLCBNU19TSEFSRUR8TVNfUkVDVVJTSVZFfSwKCQl7InJzbGF2ZSIsIE1TX1NMQVZFfE1TX1JFQ1VSU0lWRX0sCgkJeyJycHJpdmF0ZSIsIE1TX1NMQVZFfE1TX1JFQ1VSU0lWRX0sCgkJeyJydW5iaW5kYWJsZSIsIE1TX1VOQklOREFCTEV8TVNfUkVDVVJTSVZFfSwKCSkKCgkvLyBBbHdheXMgdW5kZXJzdG9vZC4KCgl7InJvIiwgTVNfUkRPTkxZfSwgICAgICAgIC8vIHZmcyBmbGFnCgl7InJ3Iiwgfk1TX1JET05MWX0sICAgICAgIC8vIHZmcyBmbGFnCgl7InJlbW91bnQiLCBNU19SRU1PVU5UfSwgIC8vIGFjdGlvbiBmbGFnCn07CgojZGVmaW5lIFZFQ1RPUl9TSVpFKHYpIChzaXplb2YodikgLyBzaXplb2YoKHYpWzBdKSkKCi8qIEFwcGVuZCBtb3VudCBvcHRpb25zIHRvIHN0cmluZyAqLwpzdGF0aWMgdm9pZCBhcHBlbmRfbW91bnRfb3B0aW9ucyhjaGFyICoqb2xkb3B0cywgY2hhciAqbmV3b3B0cykKewoJaWYgKCpvbGRvcHRzICYmICoqb2xkb3B0cykgewoJCS8qIGRvIG5vdCBpbnNlcnQgb3B0aW9ucyB3aGljaCBhcmUgYWxyZWFkeSB0aGVyZSAqLwoJCXdoaWxlIChuZXdvcHRzWzBdKSB7CgkJCWNoYXIgKnA7CgkJCWludCBsZW4gPSBzdHJsZW4obmV3b3B0cyk7CgkJCXAgPSBzdHJjaHIobmV3b3B0cywgJywnKTsKCQkJaWYgKHApIGxlbiA9IHAgLSBuZXdvcHRzOwoJCQlwID0gKm9sZG9wdHM7CgkJCXdoaWxlICgxKSB7CgkJCQlpZiAoIXN0cm5jbXAocCwgbmV3b3B0cywgbGVuKQoJCQkJICYmIChwW2xlbl09PScsJyB8fCBwW2xlbl09PTApKQoJCQkJCWdvdG8gc2tpcDsKCQkJCXAgPSBzdHJjaHIocCwnLCcpOwoJCQkJaWYoIXApIGJyZWFrOwoJCQkJcCsrOwoJCQl9CgkJCXAgPSB4YXNwcmludGYoIiVzLCUuKnMiLCAqb2xkb3B0cywgbGVuLCBuZXdvcHRzKTsKCQkJZnJlZSgqb2xkb3B0cyk7CgkJCSpvbGRvcHRzID0gcDsKc2tpcDoKCQkJbmV3b3B0cyArPSBsZW47CgkJCXdoaWxlIChuZXdvcHRzWzBdID09ICcsJykgbmV3b3B0cysrOwoJCX0KCX0gZWxzZSB7CgkJaWYgKEVOQUJMRV9GRUFUVVJFX0NMRUFOX1VQKSBmcmVlKCpvbGRvcHRzKTsKCQkqb2xkb3B0cyA9IHhzdHJkdXAobmV3b3B0cyk7Cgl9Cn0KCi8qIFVzZSB0aGUgbW91bnRfb3B0aW9ucyBsaXN0IHRvIHBhcnNlIG9wdGlvbnMgaW50byBmbGFncy4KICogQWxzbyByZXR1cm4gbGlzdCBvZiB1bnJlY29nbml6ZWQgb3B0aW9ucyBpZiB1bnJlY29nbml6ZWQhPU5VTEwgKi8Kc3RhdGljIGludCBwYXJzZV9tb3VudF9vcHRpb25zKGNoYXIgKm9wdGlvbnMsIGNoYXIgKip1bnJlY29nbml6ZWQpCnsKCWludCBmbGFncyA9IE1TX1NJTEVOVDsKCgkvLyBMb29wIHRocm91Z2ggb3B0aW9ucwoJZm9yICg7OykgewoJCWludCBpOwoJCWNoYXIgKmNvbW1hID0gc3RyY2hyKG9wdGlvbnMsICcsJyk7CgoJCWlmIChjb21tYSkgKmNvbW1hID0gMDsKCgkJLy8gRmluZCB0aGlzIG9wdGlvbiBpbiBtb3VudF9vcHRpb25zCgkJZm9yIChpID0gMDsgaSA8IFZFQ1RPUl9TSVpFKG1vdW50X29wdGlvbnMpOyBpKyspIHsKCQkJaWYgKCFzdHJjYXNlY21wKG1vdW50X29wdGlvbnNbaV0ubmFtZSwgb3B0aW9ucykpIHsKCQkJCWxvbmcgZmwgPSBtb3VudF9vcHRpb25zW2ldLmZsYWdzOwoJCQkJaWYgKGZsIDwgMCkgZmxhZ3MgJj0gZmw7CgkJCQllbHNlIGZsYWdzIHw9IGZsOwoJCQkJYnJlYWs7CgkJCX0KCQl9CgkJLy8gSWYgdW5yZWNvZ25pemVkIG5vdCBOVUxMLCBhcHBlbmQgdW5yZWNvZ25pemVkIG1vdW50IG9wdGlvbnMgKi8KCQlpZiAodW5yZWNvZ25pemVkICYmIGkgPT0gVkVDVE9SX1NJWkUobW91bnRfb3B0aW9ucykpIHsKCQkJLy8gQWRkIGl0IHRvIHN0cmZsYWdzLCB0byBwYXNzIG9uIHRvIGtlcm5lbAoJCQlpID0gKnVucmVjb2duaXplZCA/IHN0cmxlbigqdW5yZWNvZ25pemVkKSA6IDA7CgkJCSp1bnJlY29nbml6ZWQgPSB4cmVhbGxvYygqdW5yZWNvZ25pemVkLCBpK3N0cmxlbihvcHRpb25zKSsyKTsKCgkJCS8vIENvbW1hIHNlcGFyYXRlZCBpZiBpdCdzIG5vdCB0aGUgZmlyc3Qgb25lCgkJCWlmIChpKSAoKnVucmVjb2duaXplZClbaSsrXSA9ICcsJzsKCQkJc3RyY3B5KCgqdW5yZWNvZ25pemVkKStpLCBvcHRpb25zKTsKCQl9CgoJCS8vIEFkdmFuY2UgdG8gbmV4dCBvcHRpb24sIG9yIGZpbmlzaAoJCWlmIChjb21tYSkgewoJCQkqY29tbWEgPSAnLCc7CgkJCW9wdGlvbnMgPSArK2NvbW1hOwoJCX0gZWxzZSBicmVhazsKCX0KCglyZXR1cm4gZmxhZ3M7Cn0KCi8vIFJldHVybiBhIGxpc3Qgb2YgYWxsIGJsb2NrIGRldmljZSBiYWNrZWQgZmlsZXN5c3RlbXMKCnN0YXRpYyBsbGlzdF90ICpnZXRfYmxvY2tfYmFja2VkX2ZpbGVzeXN0ZW1zKHZvaWQpCnsKCXN0YXRpYyBjb25zdCBjaGFyICpjb25zdCBmaWxlc3lzdGVtc1tdID0gewoJCSIvZXRjL2ZpbGVzeXN0ZW1zIiwKCQkiL3Byb2MvZmlsZXN5c3RlbXMiLAoJCTAKCX07CgljaGFyICpmcywgKmJ1ZjsKCWxsaXN0X3QgKmxpc3QgPSAwOwoJaW50IGk7CglGSUxFICpmOwoKCWZvciAoaSA9IDA7IGZpbGVzeXN0ZW1zW2ldOyBpKyspIHsKCQlmID0gZm9wZW4oZmlsZXN5c3RlbXNbaV0sICJyIik7CgkJaWYgKCFmKSBjb250aW51ZTsKCgkJd2hpbGUgKChidWYgPSB4bWFsbG9jX2dldGxpbmUoZikpICE9IDApIHsKCQkJaWYgKCFzdHJuY21wKGJ1ZiwgIm5vZGV2IiwgNSkgJiYgaXNzcGFjZShidWZbNV0pKQoJCQkJY29udGludWU7CgkJCWZzID0gc2tpcF93aGl0ZXNwYWNlKGJ1Zik7CgkJCWlmICgqZnM9PScjJyB8fCAqZnM9PScqJyB8fCAhKmZzKSBjb250aW51ZTsKCgkJCWxsaXN0X2FkZF90b19lbmQoJmxpc3QsIHhzdHJkdXAoZnMpKTsKCQkJZnJlZShidWYpOwoJCX0KCQlpZiAoRU5BQkxFX0ZFQVRVUkVfQ0xFQU5fVVApIGZjbG9zZShmKTsKCX0KCglyZXR1cm4gbGlzdDsKfQoKbGxpc3RfdCAqZnNsaXN0ID0gMDsKCiNpZiBFTkFCTEVfRkVBVFVSRV9DTEVBTl9VUApzdGF0aWMgdm9pZCBkZWxldGVfYmxvY2tfYmFja2VkX2ZpbGVzeXN0ZW1zKHZvaWQpCnsKCWxsaXN0X2ZyZWUoZnNsaXN0LCBmcmVlKTsKfQojZWxzZQp2b2lkIGRlbGV0ZV9ibG9ja19iYWNrZWRfZmlsZXN5c3RlbXModm9pZCk7CiNlbmRpZgoKI2lmIEVOQUJMRV9GRUFUVVJFX01UQUJfU1VQUE9SVApzdGF0aWMgaW50IHVzZU10YWIgPSAxOwpzdGF0aWMgaW50IGZha2VJdDsKI2Vsc2UKI2RlZmluZSB1c2VNdGFiIDAKI2RlZmluZSBmYWtlSXQgMAojZW5kaWYKCi8vIFBlcmZvcm0gYWN0dWFsIG1vdW50IG9mIHNwZWNpZmljIGZpbGVzeXN0ZW0gYXQgc3BlY2lmaWMgbG9jYXRpb24uCi8vIE5COiBtcC0+eHh4IGZpZWxkcyBtYXkgYmUgdHJhc2hlZCBvbiBleGl0CnN0YXRpYyBpbnQgbW91bnRfaXRfbm93KHN0cnVjdCBtbnRlbnQgKm1wLCBpbnQgdmZzZmxhZ3MsIGNoYXIgKmZpbHRlcm9wdHMpCnsKCWludCByYyA9IDA7CgoJaWYgKGZha2VJdCkgZ290byBtdGFiOwoKCS8vIE1vdW50LCB3aXRoIGZhbGxiYWNrIHRvIHJlYWQtb25seSBpZiBuZWNlc3NhcnkuCgoJZm9yICg7OykgewoJCXJjID0gbW91bnQobXAtPm1udF9mc25hbWUsIG1wLT5tbnRfZGlyLCBtcC0+bW50X3R5cGUsCgkJCQl2ZnNmbGFncywgZmlsdGVyb3B0cyk7CgkJaWYgKCFyYyB8fCAodmZzZmxhZ3MmTVNfUkRPTkxZKSB8fCAoZXJybm8hPUVBQ0NFUyAmJiBlcnJubyE9RVJPRlMpKQoJCQlicmVhazsKCQliYl9lcnJvcl9tc2coIiVzIGlzIHdyaXRlLXByb3RlY3RlZCwgbW91bnRpbmcgcmVhZC1vbmx5IiwKCQkJCW1wLT5tbnRfZnNuYW1lKTsKCQl2ZnNmbGFncyB8PSBNU19SRE9OTFk7Cgl9CgoJLy8gQWJvcnQgZW50aXJlbHkgaWYgcGVybWlzc2lvbiBkZW5pZWQuCgoJaWYgKHJjICYmIGVycm5vID09IEVQRVJNKQoJCWJiX2Vycm9yX21zZ19hbmRfZGllKGJiX21zZ19wZXJtX2RlbmllZF9hcmVfeW91X3Jvb3QpOwoKCS8qIElmIHRoZSBtb3VudCB3YXMgc3VjY2Vzc2Z1bCwgYW5kIHdlJ3JlIG1haW50YWluaW5nIGFuIG9sZC1zdHlsZQoJICogbXRhYiBmaWxlIGJ5IGhhbmQsIGFkZCB0aGUgbmV3IGVudHJ5IHRvIGl0IG5vdy4gKi8KIG10YWI6CglpZiAoRU5BQkxFX0ZFQVRVUkVfTVRBQl9TVVBQT1JUICYmIHVzZU10YWIgJiYgIXJjICYmICEodmZzZmxhZ3MgJiBNU19SRU1PVU5UKSkgewoJCWNoYXIgKmZzbmFtZTsKCQlGSUxFICptb3VudFRhYmxlID0gc2V0bW50ZW50KGJiX3BhdGhfbXRhYl9maWxlLCAiYSsiKTsKCQlpbnQgaTsKCgkJaWYgKCFtb3VudFRhYmxlKSB7CgkJCWJiX2Vycm9yX21zZygibm8gJXMiLGJiX3BhdGhfbXRhYl9maWxlKTsKCQkJZ290byByZXQ7CgkJfQoKCQkvLyBBZGQgdmZzIHN0cmluZyBmbGFncwoKCQlmb3IgKGk9MDsgbW91bnRfb3B0aW9uc1tpXS5mbGFncyAhPSBNU19SRU1PVU5UOyBpKyspCgkJCWlmIChtb3VudF9vcHRpb25zW2ldLmZsYWdzID4gMCAmJiAobW91bnRfb3B0aW9uc1tpXS5mbGFncyAmIHZmc2ZsYWdzKSkKCQkJCWFwcGVuZF9tb3VudF9vcHRpb25zKCYobXAtPm1udF9vcHRzKSwgbW91bnRfb3B0aW9uc1tpXS5uYW1lKTsKCgkJLy8gUmVtb3ZlIHRyYWlsaW5nIC8gKGlmIGFueSkgZnJvbSBkaXJlY3Rvcnkgd2UgbW91bnRlZCBvbgoKCQlpID0gc3RybGVuKG1wLT5tbnRfZGlyKSAtIDE7CgkJaWYgKGkgPiAwICYmIG1wLT5tbnRfZGlyW2ldID09ICcvJykgbXAtPm1udF9kaXJbaV0gPSAwOwoKCQkvLyBDb252ZXJ0IHRvIGNhbm9uaWNhbCBwYXRobmFtZXMgYXMgbmVlZGVkCgoJCW1wLT5tbnRfZGlyID0gYmJfc2ltcGxpZnlfcGF0aChtcC0+bW50X2Rpcik7CgkJZnNuYW1lID0gMDsKCQlpZiAoIW1wLT5tbnRfdHlwZSB8fCAhKm1wLT5tbnRfdHlwZSkgeyAvKiBiaW5kIG1vdW50ICovCgkJCW1wLT5tbnRfZnNuYW1lID0gZnNuYW1lID0gYmJfc2ltcGxpZnlfcGF0aChtcC0+bW50X2ZzbmFtZSk7CgkJCW1wLT5tbnRfdHlwZSA9ICJiaW5kIjsKCQl9CgkJbXAtPm1udF9mcmVxID0gbXAtPm1udF9wYXNzbm8gPSAwOwoKCQkvLyBXcml0ZSBhbmQgY2xvc2UuCgoJCWFkZG1udGVudChtb3VudFRhYmxlLCBtcCk7CgkJZW5kbW50ZW50KG1vdW50VGFibGUpOwoJCWlmIChFTkFCTEVfRkVBVFVSRV9DTEVBTl9VUCkgewoJCQlmcmVlKG1wLT5tbnRfZGlyKTsKCQkJZnJlZShmc25hbWUpOwoJCX0KCX0KIHJldDoKCXJldHVybiByYzsKfQoKI2lmIEVOQUJMRV9GRUFUVVJFX01PVU5UX05GUwoKLyoKICogTGludXggTkZTIG1vdW50CiAqIENvcHlyaWdodCAoQykgMTk5MyBSaWNrIFNsYWRrZXkgPGpyc0B3b3JsZC5zdGQuY29tPgogKgogKiBMaWNlbnNlZCB1bmRlciBHUEx2Miwgc2VlIGZpbGUgTElDRU5TRSBpbiB0aGlzIHRhcmJhbGwgZm9yIGRldGFpbHMuCiAqCiAqIFdlZCBGZWIgIDggMTI6NTE6NDggMTk5NSwgYmlyb0B5Z2dkcmFzaWwuY29tIChSb3NzIEJpcm8pOiBhbGxvdyBhbGwgcG9ydAogKiBudW1iZXJzIHRvIGJlIHNwZWNpZmllZCBvbiB0aGUgY29tbWFuZCBsaW5lLgogKgogKiBGcmksIDggTWFyIDE5OTYgMTg6MDE6MzksIFN3ZW4gVGh1ZW1tbGVyIDxzd2VuQHVuaS1wYWRlcmJvcm4uZGU+OgogKiBPbWl0IHRoZSBjYWxsIHRvIGNvbm5lY3QoKSBmb3IgTGludXggdmVyc2lvbiAxLjMuMTEgb3IgbGF0ZXIuCiAqCiAqIFdlZCBPY3QgIDEgMjM6NTU6MjggMTk5NzogRGljayBTdHJlZWZsYW5kIDxkaWNrX3N0cmVlZmxhbmRAdGFza2luZy5jb20+CiAqIEltcGxlbWVudGVkIHRoZSAiYmciLCAiZmciIGFuZCAicmV0cnkiIG1vdW50IG9wdGlvbnMgZm9yIE5GUy4KICoKICogMTk5OS0wMi0yMiBBcmthZGl1c3ogTWm2a2lld2ljeiA8bWlzaWVrQG1pc2llay5ldS5vcmc+CiAqIC0gYWRkZWQgTmF0aXZlIExhbmd1YWdlIFN1cHBvcnQKICoKICogTW9kaWZpZWQgYnkgT2xhZiBLaXJjaCBhbmQgVHJvbmQgTXlrbGVidXN0IGZvciBuZXcgTkZTIGNvZGUsCiAqIHBsdXMgTkZTdjMgc3R1ZmYuCiAqLwoKLyogVGhpcyBpcyBqdXN0IGEgd2FybmluZyBvZiBhIGNvbW1vbiBtaXN0YWtlLiAgUG9zc2libHkgdGhpcyBzaG91bGQgYmUgYQogKiB1Y2xpYmMgZmFxIGVudHJ5IHJhdGhlciB0aGFuIGluIGJ1c3lib3guLi4gKi8KI2lmIGRlZmluZWQoX19VQ0xJQkNfXykgJiYgISBkZWZpbmVkKF9fVUNMSUJDX0hBU19SUENfXykKI2Vycm9yICJZb3UgbmVlZCB0byBidWlsZCB1Q2xpYmMgd2l0aCBVQ0xJQkNfSEFTX1JQQyBmb3IgTkZTIHN1cHBvcnQuIgojZW5kaWYKCiNkZWZpbmUgTU9VTlRQT1JUIDYzNQojZGVmaW5lIE1OVFBBVEhMRU4gMTAyNAojZGVmaW5lIE1OVE5BTUxFTiAyNTUKI2RlZmluZSBGSFNJWkUgMzIKI2RlZmluZSBGSFNJWkUzIDY0Cgp0eXBlZGVmIGNoYXIgZmhhbmRsZVtGSFNJWkVdOwoKdHlwZWRlZiBzdHJ1Y3QgewoJdW5zaWduZWQgaW50IGZoYW5kbGUzX2xlbjsKCWNoYXIgKmZoYW5kbGUzX3ZhbDsKfSBmaGFuZGxlMzsKCmVudW0gbW91bnRzdGF0MyB7CglNTlRfT0sgPSAwLAoJTU5UM0VSUl9QRVJNID0gMSwKCU1OVDNFUlJfTk9FTlQgPSAyLAoJTU5UM0VSUl9JTyA9IDUsCglNTlQzRVJSX0FDQ0VTID0gMTMsCglNTlQzRVJSX05PVERJUiA9IDIwLAoJTU5UM0VSUl9JTlZBTCA9IDIyLAoJTU5UM0VSUl9OQU1FVE9PTE9ORyA9IDYzLAoJTU5UM0VSUl9OT1RTVVBQID0gMTAwMDQsCglNTlQzRVJSX1NFUlZFUkZBVUxUID0gMTAwMDYsCn07CnR5cGVkZWYgZW51bSBtb3VudHN0YXQzIG1vdW50c3RhdDM7CgpzdHJ1Y3QgZmhzdGF0dXMgewoJdW5zaWduZWQgaW50IGZoc19zdGF0dXM7Cgl1bmlvbiB7CgkJZmhhbmRsZSBmaHNfZmhhbmRsZTsKCX0gZmhzdGF0dXNfdTsKfTsKdHlwZWRlZiBzdHJ1Y3QgZmhzdGF0dXMgZmhzdGF0dXM7CgpzdHJ1Y3QgbW91bnRyZXMzX29rIHsKCWZoYW5kbGUzIGZoYW5kbGU7CglzdHJ1Y3QgewoJCXVuc2lnbmVkIGludCBhdXRoX2ZsYXZvdXJzX2xlbjsKCQljaGFyICphdXRoX2ZsYXZvdXJzX3ZhbDsKCX0gYXV0aF9mbGF2b3VyczsKfTsKdHlwZWRlZiBzdHJ1Y3QgbW91bnRyZXMzX29rIG1vdW50cmVzM19vazsKCnN0cnVjdCBtb3VudHJlczMgewoJbW91bnRzdGF0MyBmaHNfc3RhdHVzOwoJdW5pb24gewoJCW1vdW50cmVzM19vayBtb3VudGluZm87Cgl9IG1vdW50cmVzM191Owp9Owp0eXBlZGVmIHN0cnVjdCBtb3VudHJlczMgbW91bnRyZXMzOwoKdHlwZWRlZiBjaGFyICpkaXJwYXRoOwoKdHlwZWRlZiBjaGFyICpuYW1lOwoKdHlwZWRlZiBzdHJ1Y3QgbW91bnRib2R5ICptb3VudGxpc3Q7CgpzdHJ1Y3QgbW91bnRib2R5IHsKCW5hbWUgbWxfaG9zdG5hbWU7CglkaXJwYXRoIG1sX2RpcmVjdG9yeTsKCW1vdW50bGlzdCBtbF9uZXh0Owp9Owp0eXBlZGVmIHN0cnVjdCBtb3VudGJvZHkgbW91bnRib2R5OwoKdHlwZWRlZiBzdHJ1Y3QgZ3JvdXBub2RlICpncm91cHM7CgpzdHJ1Y3QgZ3JvdXBub2RlIHsKCW5hbWUgZ3JfbmFtZTsKCWdyb3VwcyBncl9uZXh0Owp9Owp0eXBlZGVmIHN0cnVjdCBncm91cG5vZGUgZ3JvdXBub2RlOwoKdHlwZWRlZiBzdHJ1Y3QgZXhwb3J0bm9kZSAqZXhwb3J0czsKCnN0cnVjdCBleHBvcnRub2RlIHsKCWRpcnBhdGggZXhfZGlyOwoJZ3JvdXBzIGV4X2dyb3VwczsKCWV4cG9ydHMgZXhfbmV4dDsKfTsKdHlwZWRlZiBzdHJ1Y3QgZXhwb3J0bm9kZSBleHBvcnRub2RlOwoKc3RydWN0IHBwYXRoY25mIHsKCWludCBwY19saW5rX21heDsKCXNob3J0IHBjX21heF9jYW5vbjsKCXNob3J0IHBjX21heF9pbnB1dDsKCXNob3J0IHBjX25hbWVfbWF4OwoJc2hvcnQgcGNfcGF0aF9tYXg7CglzaG9ydCBwY19waXBlX2J1ZjsKCXVfY2hhciBwY192ZGlzYWJsZTsKCWNoYXIgcGNfeHh4OwoJc2hvcnQgcGNfbWFza1syXTsKfTsKdHlwZWRlZiBzdHJ1Y3QgcHBhdGhjbmYgcHBhdGhjbmY7CgojZGVmaW5lIE1PVU5UUFJPRyAxMDAwMDUKI2RlZmluZSBNT1VOVFZFUlMgMQoKI2RlZmluZSBNT1VOVFBST0NfTlVMTCAwCiNkZWZpbmUgTU9VTlRQUk9DX01OVCAxCiNkZWZpbmUgTU9VTlRQUk9DX0RVTVAgMgojZGVmaW5lIE1PVU5UUFJPQ19VTU5UIDMKI2RlZmluZSBNT1VOVFBST0NfVU1OVEFMTCA0CiNkZWZpbmUgTU9VTlRQUk9DX0VYUE9SVCA1CiNkZWZpbmUgTU9VTlRQUk9DX0VYUE9SVEFMTCA2CgojZGVmaW5lIE1PVU5UVkVSU19QT1NJWCAyCgojZGVmaW5lIE1PVU5UUFJPQ19QQVRIQ09ORiA3CgojZGVmaW5lIE1PVU5UX1YzIDMKCiNkZWZpbmUgTU9VTlRQUk9DM19OVUxMIDAKI2RlZmluZSBNT1VOVFBST0MzX01OVCAxCiNkZWZpbmUgTU9VTlRQUk9DM19EVU1QIDIKI2RlZmluZSBNT1VOVFBST0MzX1VNTlQgMwojZGVmaW5lIE1PVU5UUFJPQzNfVU1OVEFMTCA0CiNkZWZpbmUgTU9VTlRQUk9DM19FWFBPUlQgNQoKZW51bSB7CiNpZm5kZWYgTkZTX0ZIU0laRQoJTkZTX0ZIU0laRSA9IDMyLAojZW5kaWYKI2lmbmRlZiBORlNfUE9SVAoJTkZTX1BPUlQgPSAyMDQ5CiNlbmRpZgp9OwoKLyoKICogV2Ugd2FudCB0byBiZSBhYmxlIHRvIGNvbXBpbGUgbW91bnQgb24gb2xkIGtlcm5lbHMgaW4gc3VjaCBhIHdheQogKiB0aGF0IHRoZSBiaW5hcnkgd2lsbCB3b3JrIHdlbGwgb24gbW9yZSByZWNlbnQga2VybmVscy4KICogVGh1cywgaWYgbmVjZXNzYXJ5IHdlIHRlYWNoIG5mc21vdW50LmMgdGhlIHN0cnVjdHVyZSBvZiBuZXcgZmllbGRzCiAqIHRoYXQgd2lsbCBjb21lIGxhdGVyLgogKgogKiBNb3Jlb3ZlciwgdGhlIG5ldyBrZXJuZWwgaW5jbHVkZXMgY29uZmxpY3Qgd2l0aCBnbGliYyBpbmNsdWRlcwogKiBzbyBpdCBpcyBlYXNpZXN0IHRvIGlnbm9yZSB0aGUga2VybmVsIGFsdG9nZXRoZXIgKGF0IGNvbXBpbGUgdGltZSkuCiAqLwoKc3RydWN0IG5mczJfZmggewoJY2hhciAgICAgICAgICAgICAgICAgICAgZGF0YVszMl07Cn07CnN0cnVjdCBuZnMzX2ZoIHsKCXVuc2lnbmVkIHNob3J0ICAgICAgICAgIHNpemU7Cgl1bnNpZ25lZCBjaGFyICAgICAgICAgICBkYXRhWzY0XTsKfTsKCnN0cnVjdCBuZnNfbW91bnRfZGF0YSB7CglpbnQJCXZlcnNpb247CQkvKiAxICovCglpbnQJCWZkOwkJCS8qIDEgKi8KCXN0cnVjdCBuZnMyX2ZoCW9sZF9yb290OwkJLyogMSAqLwoJaW50CQlmbGFnczsJCQkvKiAxICovCglpbnQJCXJzaXplOwkJCS8qIDEgKi8KCWludAkJd3NpemU7CQkJLyogMSAqLwoJaW50CQl0aW1lbzsJCQkvKiAxICovCglpbnQJCXJldHJhbnM7CQkvKiAxICovCglpbnQJCWFjcmVnbWluOwkJLyogMSAqLwoJaW50CQlhY3JlZ21heDsJCS8qIDEgKi8KCWludAkJYWNkaXJtaW47CQkvKiAxICovCglpbnQJCWFjZGlybWF4OwkJLyogMSAqLwoJc3RydWN0IHNvY2thZGRyX2luIGFkZHI7CQkvKiAxICovCgljaGFyCQlob3N0bmFtZVsyNTZdOwkJLyogMSAqLwoJaW50CQluYW1sZW47CQkJLyogMiAqLwoJdW5zaWduZWQgaW50CWJzaXplOwkJCS8qIDMgKi8KCXN0cnVjdCBuZnMzX2ZoCXJvb3Q7CQkJLyogNCAqLwp9OwoKLyogYml0cyBpbiB0aGUgZmxhZ3MgZmllbGQgKi8KZW51bSB7CglORlNfTU9VTlRfU09GVCA9IDB4MDAwMSwJLyogMSAqLwoJTkZTX01PVU5UX0lOVFIgPSAweDAwMDIsCS8qIDEgKi8KCU5GU19NT1VOVF9TRUNVUkUgPSAweDAwMDQsCS8qIDEgKi8KCU5GU19NT1VOVF9QT1NJWCA9IDB4MDAwOCwJLyogMSAqLwoJTkZTX01PVU5UX05PQ1RPID0gMHgwMDEwLAkvKiAxICovCglORlNfTU9VTlRfTk9BQyA9IDB4MDAyMCwJLyogMSAqLwoJTkZTX01PVU5UX1RDUCA9IDB4MDA0MCwJCS8qIDIgKi8KCU5GU19NT1VOVF9WRVIzID0gMHgwMDgwLAkvKiAzICovCglORlNfTU9VTlRfS0VSQkVST1MgPSAweDAxMDAsCS8qIDMgKi8KCU5GU19NT1VOVF9OT05MTSA9IDB4MDIwMAkvKiAzICovCn07CgoKLyoKICogV2UgbmVlZCB0byB0cmFuc2xhdGUgYmV0d2VlbiBuZnMgc3RhdHVzIHJldHVybiB2YWx1ZXMgYW5kCiAqIHRoZSBsb2NhbCBlcnJubyB2YWx1ZXMgd2hpY2ggbWF5IG5vdCBiZSB0aGUgc2FtZS4KICoKICogQW5kcmVhcyBTY2h3YWIgPHNjaHdhYkBMUzUuaW5mb3JtYXRpay51bmktZG9ydG11bmQuZGU+OiBjaGFuZ2UgZXJybm86CiAqICJhZnRlciAjaW5jbHVkZSA8ZXJybm8uaD4gdGhlIHN5bWJvbCBlcnJubyBpcyByZXNlcnZlZCBmb3IgYW55IHVzZSwKICogIGl0IGNhbm5vdCBldmVuIGJlIHVzZWQgYXMgYSBzdHJ1Y3QgdGFnIG9yIGZpZWxkIG5hbWUiLgogKi8KCiNpZm5kZWYgRURRVU9UCiNkZWZpbmUgRURRVU9UCUVOT1NQQwojZW5kaWYKCi8vIENvbnZlcnQgZWFjaCBORlNFUlJfQkxBSCBpbnRvIEVCTEFICgpzdGF0aWMgY29uc3Qgc3RydWN0IHsKCWludCBzdGF0OwoJaW50IGVycm51bTsKfSBuZnNfZXJydGJsW10gPSB7Cgl7MCwwfSwgezEsRVBFUk19LCB7MixFTk9FTlR9LCB7NSxFSU99LCB7NixFTlhJT30sIHsxMyxFQUNDRVN9LCB7MTcsRUVYSVNUfSwKCXsxOSxFTk9ERVZ9LCB7MjAsRU5PVERJUn0sIHsyMSxFSVNESVJ9LCB7MjIsRUlOVkFMfSwgezI3LEVGQklHfSwKCXsyOCxFTk9TUEN9LCB7MzAsRVJPRlN9LCB7NjMsRU5BTUVUT09MT05HfSwgezY2LEVOT1RFTVBUWX0sIHs2OSxFRFFVT1R9LAoJezcwLEVTVEFMRX0sIHs3MSxFUkVNT1RFfSwgey0xLEVJT30KfTsKCnN0YXRpYyBjaGFyICpuZnNfc3RyZXJyb3IoaW50IHN0YXR1cykKewoJaW50IGk7CglzdGF0aWMgY2hhciBidWZbc2l6ZW9mKCJ1bmtub3duIG5mcyBzdGF0dXMgcmV0dXJuIHZhbHVlOiAiKSArIHNpemVvZihpbnQpKjNdOwoKCWZvciAoaSA9IDA7IG5mc19lcnJ0YmxbaV0uc3RhdCAhPSAtMTsgaSsrKSB7CgkJaWYgKG5mc19lcnJ0YmxbaV0uc3RhdCA9PSBzdGF0dXMpCgkJCXJldHVybiBzdHJlcnJvcihuZnNfZXJydGJsW2ldLmVycm51bSk7Cgl9CglzcHJpbnRmKGJ1ZiwgInVua25vd24gbmZzIHN0YXR1cyByZXR1cm4gdmFsdWU6ICVkIiwgc3RhdHVzKTsKCXJldHVybiBidWY7Cn0KCnN0YXRpYyBib29sX3QgeGRyX2ZoYW5kbGUoWERSICp4ZHJzLCBmaGFuZGxlIG9ianApCnsKCWlmICgheGRyX29wYXF1ZSh4ZHJzLCBvYmpwLCBGSFNJWkUpKQoJCSByZXR1cm4gRkFMU0U7CglyZXR1cm4gVFJVRTsKfQoKc3RhdGljIGJvb2xfdCB4ZHJfZmhzdGF0dXMoWERSICp4ZHJzLCBmaHN0YXR1cyAqb2JqcCkKewoJaWYgKCF4ZHJfdV9pbnQoeGRycywgJm9ianAtPmZoc19zdGF0dXMpKQoJCSByZXR1cm4gRkFMU0U7Cglzd2l0Y2ggKG9ianAtPmZoc19zdGF0dXMpIHsKCWNhc2UgMDoKCQlpZiAoIXhkcl9maGFuZGxlKHhkcnMsIG9ianAtPmZoc3RhdHVzX3UuZmhzX2ZoYW5kbGUpKQoJCQkgcmV0dXJuIEZBTFNFOwoJCWJyZWFrOwoJZGVmYXVsdDoKCQlicmVhazsKCX0KCXJldHVybiBUUlVFOwp9CgpzdGF0aWMgYm9vbF90IHhkcl9kaXJwYXRoKFhEUiAqeGRycywgZGlycGF0aCAqb2JqcCkKewoJaWYgKCF4ZHJfc3RyaW5nKHhkcnMsIG9ianAsIE1OVFBBVEhMRU4pKQoJCSByZXR1cm4gRkFMU0U7CglyZXR1cm4gVFJVRTsKfQoKc3RhdGljIGJvb2xfdCB4ZHJfZmhhbmRsZTMoWERSICp4ZHJzLCBmaGFuZGxlMyAqb2JqcCkKewoJaWYgKCF4ZHJfYnl0ZXMoeGRycywgKGNoYXIgKiopJm9ianAtPmZoYW5kbGUzX3ZhbCwgKHVuc2lnbmVkIGludCAqKSAmb2JqcC0+ZmhhbmRsZTNfbGVuLCBGSFNJWkUzKSkKCQkgcmV0dXJuIEZBTFNFOwoJcmV0dXJuIFRSVUU7Cn0KCnN0YXRpYyBib29sX3QgeGRyX21vdW50cmVzM19vayhYRFIgKnhkcnMsIG1vdW50cmVzM19vayAqb2JqcCkKewoJaWYgKCF4ZHJfZmhhbmRsZTMoeGRycywgJm9ianAtPmZoYW5kbGUpKQoJCXJldHVybiBGQUxTRTsKCWlmICgheGRyX2FycmF5KHhkcnMsICYob2JqcC0+YXV0aF9mbGF2b3Vycy5hdXRoX2ZsYXZvdXJzX3ZhbCksICYob2JqcC0+YXV0aF9mbGF2b3Vycy5hdXRoX2ZsYXZvdXJzX2xlbiksIH4wLAoJCQkJc2l6ZW9mIChpbnQpLCAoeGRycHJvY190KSB4ZHJfaW50KSkKCQlyZXR1cm4gRkFMU0U7CglyZXR1cm4gVFJVRTsKfQoKc3RhdGljIGJvb2xfdCB4ZHJfbW91bnRzdGF0MyhYRFIgKnhkcnMsIG1vdW50c3RhdDMgKm9ianApCnsKCWlmICgheGRyX2VudW0oeGRycywgKGVudW1fdCAqKSBvYmpwKSkKCQkgcmV0dXJuIEZBTFNFOwoJcmV0dXJuIFRSVUU7Cn0KCnN0YXRpYyBib29sX3QgeGRyX21vdW50cmVzMyhYRFIgKnhkcnMsIG1vdW50cmVzMyAqb2JqcCkKewoJaWYgKCF4ZHJfbW91bnRzdGF0Myh4ZHJzLCAmb2JqcC0+ZmhzX3N0YXR1cykpCgkJcmV0dXJuIEZBTFNFOwoJc3dpdGNoIChvYmpwLT5maHNfc3RhdHVzKSB7CgljYXNlIE1OVF9PSzoKCQlpZiAoIXhkcl9tb3VudHJlczNfb2soeGRycywgJm9ianAtPm1vdW50cmVzM191Lm1vdW50aW5mbykpCgkJCSByZXR1cm4gRkFMU0U7CgkJYnJlYWs7CglkZWZhdWx0OgoJCWJyZWFrOwoJfQoJcmV0dXJuIFRSVUU7Cn0KCiNkZWZpbmUgTUFYX05GU1BST1QgKChuZnNfbW91bnRfdmVyc2lvbiA+PSA0KSA/IDMgOiAyKQoKLyoKICogbmZzX21vdW50X3ZlcnNpb24gYWNjb3JkaW5nIHRvIHRoZSBzb3VyY2VzIHNlZW4gYXQgY29tcGlsZSB0aW1lLgogKi8Kc3RhdGljIGludCBuZnNfbW91bnRfdmVyc2lvbjsKc3RhdGljIGludCBrZXJuZWxfdmVyc2lvbjsKCi8qCiAqIFVuZm9ydHVuYXRlbHksIHRoZSBrZXJuZWwgcHJpbnRzIGFubm95aW5nIGNvbnNvbGUgbWVzc2FnZXMKICogaW4gY2FzZSBvZiBhbiB1bmV4cGVjdGVkIG5mcyBtb3VudCB2ZXJzaW9uIChpbnN0ZWFkIG9mCiAqIGp1c3QgcmV0dXJuaW5nIHNvbWUgZXJyb3IpLiAgVGhlcmVmb3JlIHdlJ2xsIGhhdmUgdG8gdHJ5CiAqIGFuZCBmaWd1cmUgb3V0IHdoYXQgdmVyc2lvbiB0aGUga2VybmVsIGV4cGVjdHMuCiAqCiAqIFZhcmlhYmxlczoKICoJS0VSTkVMX05GU19NT1VOVF9WRVJTSU9OOiBrZXJuZWwgc291cmNlcyBhdCBjb21waWxlIHRpbWUKICoJTkZTX01PVU5UX1ZFUlNJT046IHRoZXNlIG5mc21vdW50IHNvdXJjZXMgYXQgY29tcGlsZSB0aW1lCiAqCW5mc19tb3VudF92ZXJzaW9uOiB2ZXJzaW9uIHRoaXMgc291cmNlIGFuZCBydW5uaW5nIGtlcm5lbCBjYW4gaGFuZGxlCiAqLwpzdGF0aWMgdm9pZApmaW5kX2tlcm5lbF9uZnNfbW91bnRfdmVyc2lvbih2b2lkKQp7CglpZiAoa2VybmVsX3ZlcnNpb24pCgkJcmV0dXJuOwoKCW5mc19tb3VudF92ZXJzaW9uID0gNDsgLyogZGVmYXVsdCAqLwoKCWtlcm5lbF92ZXJzaW9uID0gZ2V0X2xpbnV4X3ZlcnNpb25fY29kZSgpOwoJaWYgKGtlcm5lbF92ZXJzaW9uKSB7CgkJaWYgKGtlcm5lbF92ZXJzaW9uIDwgS0VSTkVMX1ZFUlNJT04oMiwxLDMyKSkKCQkJbmZzX21vdW50X3ZlcnNpb24gPSAxOwoJCWVsc2UgaWYgKGtlcm5lbF92ZXJzaW9uIDwgS0VSTkVMX1ZFUlNJT04oMiwyLDE4KSB8fAoJCQkJKGtlcm5lbF92ZXJzaW9uID49IEtFUk5FTF9WRVJTSU9OKDIsMywwKSAmJgoJCQkJIGtlcm5lbF92ZXJzaW9uIDwgS0VSTkVMX1ZFUlNJT04oMiwzLDk5KSkpCgkJCW5mc19tb3VudF92ZXJzaW9uID0gMzsKCQkvKiBlbHNlIHY0IHNpbmNlIDIuMy45OXByZTQgKi8KCX0KfQoKc3RhdGljIHN0cnVjdCBwbWFwICoKZ2V0X21vdW50cG9ydChzdHJ1Y3Qgc29ja2FkZHJfaW4gKnNlcnZlcl9hZGRyLAoJbG9uZyB1bnNpZ25lZCBwcm9nLAoJbG9uZyB1bnNpZ25lZCB2ZXJzaW9uLAoJbG9uZyB1bnNpZ25lZCBwcm90bywKCWxvbmcgdW5zaWduZWQgcG9ydCkKewoJc3RydWN0IHBtYXBsaXN0ICpwbWFwOwoJc3RhdGljIHN0cnVjdCBwbWFwIHAgPSB7MCwgMCwgMCwgMH07CgoJc2VydmVyX2FkZHItPnNpbl9wb3J0ID0gUE1BUFBPUlQ7CglwbWFwID0gcG1hcF9nZXRtYXBzKHNlcnZlcl9hZGRyKTsKCglpZiAodmVyc2lvbiA+IE1BWF9ORlNQUk9UKQoJCXZlcnNpb24gPSBNQVhfTkZTUFJPVDsKCWlmICghcHJvZykKCQlwcm9nID0gTU9VTlRQUk9HOwoJcC5wbV9wcm9nID0gcHJvZzsKCXAucG1fdmVycyA9IHZlcnNpb247CglwLnBtX3Byb3QgPSBwcm90bzsKCXAucG1fcG9ydCA9IHBvcnQ7CgoJd2hpbGUgKHBtYXApIHsKCQlpZiAocG1hcC0+cG1sX21hcC5wbV9wcm9nICE9IHByb2cpCgkJCWdvdG8gbmV4dDsKCQlpZiAoIXZlcnNpb24gJiYgcC5wbV92ZXJzID4gcG1hcC0+cG1sX21hcC5wbV92ZXJzKQoJCQlnb3RvIG5leHQ7CgkJaWYgKHZlcnNpb24gPiAyICYmIHBtYXAtPnBtbF9tYXAucG1fdmVycyAhPSB2ZXJzaW9uKQoJCQlnb3RvIG5leHQ7CgkJaWYgKHZlcnNpb24gJiYgdmVyc2lvbiA8PSAyICYmIHBtYXAtPnBtbF9tYXAucG1fdmVycyA+IDIpCgkJCWdvdG8gbmV4dDsKCQlpZiAocG1hcC0+cG1sX21hcC5wbV92ZXJzID4gTUFYX05GU1BST1QgfHwKCQkgICAgKHByb3RvICYmIHAucG1fcHJvdCAmJiBwbWFwLT5wbWxfbWFwLnBtX3Byb3QgIT0gcHJvdG8pIHx8CgkJICAgIChwb3J0ICYmIHBtYXAtPnBtbF9tYXAucG1fcG9ydCAhPSBwb3J0KSkKCQkJZ290byBuZXh0OwoJCW1lbWNweSgmcCwgJnBtYXAtPnBtbF9tYXAsIHNpemVvZihwKSk7Cm5leHQ6CgkJcG1hcCA9IHBtYXAtPnBtbF9uZXh0OwoJfQoJaWYgKCFwLnBtX3ZlcnMpCgkJcC5wbV92ZXJzID0gTU9VTlRWRVJTOwoJaWYgKCFwLnBtX3BvcnQpCgkJcC5wbV9wb3J0ID0gTU9VTlRQT1JUOwoJaWYgKCFwLnBtX3Byb3QpCgkJcC5wbV9wcm90ID0gSVBQUk9UT19UQ1A7CglyZXR1cm4gJnA7Cn0KCnN0YXRpYyBpbnQgZGFlbW9uaXplKHZvaWQpCnsKCWludCBmZDsKCWludCBwaWQgPSBmb3JrKCk7CglpZiAocGlkIDwgMCkgLyogZXJyb3IgKi8KCQlyZXR1cm4gLWVycm5vOwoJaWYgKHBpZCA+IDApIC8qIHBhcmVudCAqLwoJCXJldHVybiAwOwoJLyogY2hpbGQgKi8KCWZkID0geG9wZW4oYmJfZGV2X251bGwsIE9fUkRXUik7CglkdXAyKGZkLCAwKTsKCWR1cDIoZmQsIDEpOwoJZHVwMihmZCwgMik7CglpZiAoZmQgPiAyKSBjbG9zZShmZCk7CglzZXRzaWQoKTsKCW9wZW5sb2coYXBwbGV0X25hbWUsIExPR19QSUQsIExPR19EQUVNT04pOwoJbG9nbW9kZSA9IExPR01PREVfU1lTTE9HOwoJcmV0dXJuIDE7Cn0KCi8vIFRPRE8Kc3RhdGljIGlubGluZSBpbnQgd2Vfc2F3X3RoaXNfaG9zdF9iZWZvcmUoY29uc3QgY2hhciAqaG9zdG5hbWUpCnsKCXJldHVybiAwOwp9CgovKiBSUEMgc3RyZXJyb3IgYW5hbG9ncyBhcmUgdGVybWluYWxseSBpZGlvdGljOgogKiAqbWFuZGF0b3J5KiBwcmVmaXggYW5kIFxuIGF0IGVuZC4KICogVGhpcyBob3BlZnVsbHkgaGVscHMuIFVzYWdlOgogKiBlcnJvcl9tc2dfcnBjKGNsbnRfKmVycm9yKigiICIpKSAqLwpzdGF0aWMgdm9pZCBlcnJvcl9tc2dfcnBjKGNvbnN0IGNoYXIgKm1zZykKewoJaW50IGxlbjsKCXdoaWxlIChtc2dbMF0gPT0gJyAnIHx8IG1zZ1swXSA9PSAnOicpIG1zZysrOwoJbGVuID0gc3RybGVuKG1zZyk7Cgl3aGlsZSAobGVuICYmIG1zZ1tsZW4tMV0gPT0gJ1xuJykgbGVuLS07CgliYl9lcnJvcl9tc2coIiUuKnMiLCBsZW4sIG1zZyk7Cn0KCi8vIE5COiBtcC0+eHh4IGZpZWxkcyBtYXkgYmUgdHJhc2hlZCBvbiBleGl0CnN0YXRpYyBpbnQgbmZzbW91bnQoc3RydWN0IG1udGVudCAqbXAsIGludCB2ZnNmbGFncywgY2hhciAqZmlsdGVyb3B0cykKewoJQ0xJRU5UICptY2xpZW50OwoJY2hhciAqaG9zdG5hbWU7CgljaGFyICpwYXRobmFtZTsKCWNoYXIgKm1vdW50aG9zdDsKCXN0cnVjdCBuZnNfbW91bnRfZGF0YSBkYXRhOwoJY2hhciAqb3B0OwoJc3RydWN0IGhvc3RlbnQgKmhwOwoJc3RydWN0IHNvY2thZGRyX2luIHNlcnZlcl9hZGRyOwoJc3RydWN0IHNvY2thZGRyX2luIG1vdW50X3NlcnZlcl9hZGRyOwoJaW50IG1zb2NrLCBmc29jazsKCXVuaW9uIHsKCQlzdHJ1Y3QgZmhzdGF0dXMgbmZzdjI7CgkJc3RydWN0IG1vdW50cmVzMyBuZnN2MzsKCX0gc3RhdHVzOwoJaW50IGRhZW1vbml6ZWQ7CgljaGFyICpzOwoJaW50IHBvcnQ7CglpbnQgbW91bnRwb3J0OwoJaW50IHByb3RvOwoJaW50IGJnOwoJaW50IHNvZnQ7CglpbnQgaW50cjsKCWludCBwb3NpeDsKCWludCBub2N0bzsKCWludCBub2FjOwoJaW50IG5vbG9jazsKCWludCByZXRyeTsKCWludCB0Y3A7CglpbnQgbW91bnRwcm9nOwoJaW50IG1vdW50dmVyczsKCWludCBuZnNwcm9nOwoJaW50IG5mc3ZlcnM7CglpbnQgcmV0dmFsOwoKCWZpbmRfa2VybmVsX25mc19tb3VudF92ZXJzaW9uKCk7CgoJZGFlbW9uaXplZCA9IDA7Cgltb3VudGhvc3QgPSBOVUxMOwoJcmV0dmFsID0gRVRJTUVET1VUOwoJbXNvY2sgPSBmc29jayA9IC0xOwoJbWNsaWVudCA9IE5VTEw7CgoJLyogTkI6IGhvc3RuYW1lLCBtb3VudGhvc3QsIGZpbHRlcm9wdHMgbXVzdCBiZSBmcmVlKClkIHByaW9yIHRvIHJldHVybiAqLwoKCWZpbHRlcm9wdHMgPSB4c3RyZHVwKGZpbHRlcm9wdHMpOyAvKiBnb2luZyB0byB0cmFzaCBpdCBsYXRlci4uLiAqLwoKCWhvc3RuYW1lID0geHN0cmR1cChtcC0+bW50X2ZzbmFtZSk7CgkvKiBtb3VudF9tYWluKCkgZ3VhcmFudGVlcyB0aGF0ICc6JyBpcyB0aGVyZSAqLwoJcyA9IHN0cmNocihob3N0bmFtZSwgJzonKTsKCXBhdGhuYW1lID0gcyArIDE7CgkqcyA9ICdcMCc7CgkvKiBJZ25vcmUgYWxsIGJ1dCBmaXJzdCBob3N0bmFtZSBpbiByZXBsaWNhdGVkIG1vdW50cwoJICAgdW50aWwgdGhleSBjYW4gYmUgZnVsbHkgc3VwcG9ydGVkLiAobWFja0BzZ2kuY29tKSAqLwoJcyA9IHN0cmNocihob3N0bmFtZSwgJywnKTsKCWlmIChzKSB7CgkJKnMgPSAnXDAnOwoJCWJiX2Vycm9yX21zZygid2FybmluZzogbXVsdGlwbGUgaG9zdG5hbWVzIG5vdCBzdXBwb3J0ZWQiKTsKCX0KCglzZXJ2ZXJfYWRkci5zaW5fZmFtaWx5ID0gQUZfSU5FVDsKCWlmICghaW5ldF9hdG9uKGhvc3RuYW1lLCAmc2VydmVyX2FkZHIuc2luX2FkZHIpKSB7CgkJaHAgPSBnZXRob3N0YnluYW1lKGhvc3RuYW1lKTsKCQlpZiAoaHAgPT0gTlVMTCkgewoJCQliYl9oZXJyb3JfbXNnKCIlcyIsIGhvc3RuYW1lKTsKCQkJZ290byBmYWlsOwoJCX0KCQlpZiAoaHAtPmhfbGVuZ3RoID4gc2l6ZW9mKHN0cnVjdCBpbl9hZGRyKSkgewoJCQliYl9lcnJvcl9tc2coImdvdCBiYWQgaHAtPmhfbGVuZ3RoIik7CgkJCWhwLT5oX2xlbmd0aCA9IHNpemVvZihzdHJ1Y3QgaW5fYWRkcik7CgkJfQoJCW1lbWNweSgmc2VydmVyX2FkZHIuc2luX2FkZHIsCgkJCQlocC0+aF9hZGRyLCBocC0+aF9sZW5ndGgpOwoJfQoKCW1lbWNweSgmbW91bnRfc2VydmVyX2FkZHIsICZzZXJ2ZXJfYWRkciwgc2l6ZW9mKG1vdW50X3NlcnZlcl9hZGRyKSk7CgoJLyogYWRkIElQIGFkZHJlc3MgdG8gbXRhYiBvcHRpb25zIGZvciB1c2Ugd2hlbiB1bm1vdW50aW5nICovCgoJaWYgKCFtcC0+bW50X29wdHMpIHsgLyogVE9ETzogYWN0dWFsbHkgbXAtPm1udF9vcHRzIGlzIG5ldmVyIE5VTEwgKi8KCQltcC0+bW50X29wdHMgPSB4YXNwcmludGYoImFkZHI9JXMiLCBpbmV0X250b2Eoc2VydmVyX2FkZHIuc2luX2FkZHIpKTsKCX0gZWxzZSB7CgkJY2hhciAqdG1wID0geGFzcHJpbnRmKCIlcyVzYWRkcj0lcyIsIG1wLT5tbnRfb3B0cywKCQkJCQltcC0+bW50X29wdHNbMF0gPyAiLCIgOiAiIiwKCQkJCQlpbmV0X250b2Eoc2VydmVyX2FkZHIuc2luX2FkZHIpKTsKCQlmcmVlKG1wLT5tbnRfb3B0cyk7CgkJbXAtPm1udF9vcHRzID0gdG1wOwoJfQoKCS8qIFNldCBkZWZhdWx0IG9wdGlvbnMuCgkgKiByc2l6ZS93c2l6ZSAoYW5kIGJzaXplLCBmb3IgdmVyID49IDMpIGFyZSBsZWZ0IDAgaW4gb3JkZXIgdG8KCSAqIGxldCB0aGUga2VybmVsIGRlY2lkZS4KCSAqIHRpbWVvIGlzIGZpbGxlZCBpbiBhZnRlciB3ZSBrbm93IHdoZXRoZXIgaXQnbGwgYmUgVENQIG9yIFVEUC4gKi8KCW1lbXNldCgmZGF0YSwgMCwgc2l6ZW9mKGRhdGEpKTsKCWRhdGEucmV0cmFucwk9IDM7CglkYXRhLmFjcmVnbWluCT0gMzsKCWRhdGEuYWNyZWdtYXgJPSA2MDsKCWRhdGEuYWNkaXJtaW4JPSAzMDsKCWRhdGEuYWNkaXJtYXgJPSA2MDsKCWRhdGEubmFtbGVuCT0gTkFNRV9NQVg7CgoJYmcgPSAwOwoJc29mdCA9IDA7CglpbnRyID0gMDsKCXBvc2l4ID0gMDsKCW5vY3RvID0gMDsKCW5vbG9jayA9IDA7Cglub2FjID0gMDsKCXJldHJ5ID0gMTAwMDA7CQkvKiAxMDAwMCBtaW51dGVzIH4gMSB3ZWVrICovCgl0Y3AgPSAwOwoKCW1vdW50cHJvZyA9IE1PVU5UUFJPRzsKCW1vdW50dmVycyA9IDA7Cglwb3J0ID0gMDsKCW1vdW50cG9ydCA9IDA7CgluZnNwcm9nID0gMTAwMDAzOwoJbmZzdmVycyA9IDA7CgoJLyogcGFyc2Ugb3B0aW9ucyAqLwoKCWZvciAob3B0ID0gc3RydG9rKGZpbHRlcm9wdHMsICIsIik7IG9wdDsgb3B0ID0gc3RydG9rKE5VTEwsICIsIikpIHsKCQljaGFyICpvcHRlcSA9IHN0cmNocihvcHQsICc9Jyk7CgkJaWYgKG9wdGVxKSB7CgkJCWNvbnN0IGNoYXIgKmNvbnN0IG9wdGlvbnNbXSA9IHsKCQkJCS8qIDAgKi8gInJzaXplIiwKCQkJCS8qIDEgKi8gIndzaXplIiwKCQkJCS8qIDIgKi8gInRpbWVvIiwKCQkJCS8qIDMgKi8gInJldHJhbnMiLAoJCQkJLyogNCAqLyAiYWNyZWdtaW4iLAoJCQkJLyogNSAqLyAiYWNyZWdtYXgiLAoJCQkJLyogNiAqLyAiYWNkaXJtaW4iLAoJCQkJLyogNyAqLyAiYWNkaXJtYXgiLAoJCQkJLyogOCAqLyAiYWN0aW1lbyIsCgkJCQkvKiA5ICovICJyZXRyeSIsCgkJCQkvKiAxMCAqLyAicG9ydCIsCgkJCQkvKiAxMSAqLyAibW91bnRwb3J0IiwKCQkJCS8qIDEyICovICJtb3VudGhvc3QiLAoJCQkJLyogMTMgKi8gIm1vdW50cHJvZyIsCgkJCQkvKiAxNCAqLyAibW91bnR2ZXJzIiwKCQkJCS8qIDE1ICovICJuZnNwcm9nIiwKCQkJCS8qIDE2ICovICJuZnN2ZXJzIiwKCQkJCS8qIDE3ICovICJ2ZXJzIiwKCQkJCS8qIDE4ICovICJwcm90byIsCgkJCQkvKiAxOSAqLyAibmFtbGVuIiwKCQkJCS8qIDIwICovICJhZGRyIiwKCQkJCU5VTEwKCQkJfTsKCQkJaW50IHZhbCA9IHhhdG9pX3Uob3B0ZXEgKyAxKTsKCQkJKm9wdGVxID0gJ1wwJzsKCQkJc3dpdGNoIChpbmRleF9pbl9zdHJfYXJyYXkob3B0aW9ucywgb3B0KSkgewoJCQljYXNlIDA6IC8vICJyc2l6ZSIKCQkJCWRhdGEucnNpemUgPSB2YWw7CgkJCQlicmVhazsKCQkJY2FzZSAxOiAvLyAid3NpemUiCgkJCQlkYXRhLndzaXplID0gdmFsOwoJCQkJYnJlYWs7CgkJCWNhc2UgMjogLy8gInRpbWVvIgoJCQkJZGF0YS50aW1lbyA9IHZhbDsKCQkJCWJyZWFrOwoJCQljYXNlIDM6IC8vICJyZXRyYW5zIgoJCQkJZGF0YS5yZXRyYW5zID0gdmFsOwoJCQkJYnJlYWs7CgkJCWNhc2UgNDogLy8gImFjcmVnbWluIgoJCQkJZGF0YS5hY3JlZ21pbiA9IHZhbDsKCQkJCWJyZWFrOwoJCQljYXNlIDU6IC8vICJhY3JlZ21heCIKCQkJCWRhdGEuYWNyZWdtYXggPSB2YWw7CgkJCQlicmVhazsKCQkJY2FzZSA2OiAvLyAiYWNkaXJtaW4iCgkJCQlkYXRhLmFjZGlybWluID0gdmFsOwoJCQkJYnJlYWs7CgkJCWNhc2UgNzogLy8gImFjZGlybWF4IgoJCQkJZGF0YS5hY2Rpcm1heCA9IHZhbDsKCQkJCWJyZWFrOwoJCQljYXNlIDg6IC8vICJhY3RpbWVvIgoJCQkJZGF0YS5hY3JlZ21pbiA9IHZhbDsKCQkJCWRhdGEuYWNyZWdtYXggPSB2YWw7CgkJCQlkYXRhLmFjZGlybWluID0gdmFsOwoJCQkJZGF0YS5hY2Rpcm1heCA9IHZhbDsKCQkJCWJyZWFrOwoJCQljYXNlIDk6IC8vICJyZXRyeSIKCQkJCXJldHJ5ID0gdmFsOwoJCQkJYnJlYWs7CgkJCWNhc2UgMTA6IC8vICJwb3J0IgoJCQkJcG9ydCA9IHZhbDsKCQkJCWJyZWFrOwoJCQljYXNlIDExOiAvLyAibW91bnRwb3J0IgoJCQkJbW91bnRwb3J0ID0gdmFsOwoJCQkJYnJlYWs7CgkJCWNhc2UgMTI6IC8vICJtb3VudGhvc3QiCgkJCQltb3VudGhvc3QgPSB4c3RybmR1cChvcHRlcSsxLAoJCQkJCQlzdHJjc3BuKG9wdGVxKzEsIiBcdFxuXHIsIikpOwoJCQkJYnJlYWs7CgkJCWNhc2UgMTM6IC8vICJtb3VudHByb2ciCgkJCQltb3VudHByb2cgPSB2YWw7CgkJCQlicmVhazsKCQkJY2FzZSAxNDogLy8gIm1vdW50dmVycyIKCQkJCW1vdW50dmVycyA9IHZhbDsKCQkJCWJyZWFrOwoJCQljYXNlIDE1OiAvLyAibmZzcHJvZyIKCQkJCW5mc3Byb2cgPSB2YWw7CgkJCQlicmVhazsKCQkJY2FzZSAxNjogLy8gIm5mc3ZlcnMiCgkJCWNhc2UgMTc6IC8vICJ2ZXJzIgoJCQkJbmZzdmVycyA9IHZhbDsKCQkJCWJyZWFrOwoJCQljYXNlIDE4OiAvLyAicHJvdG8iCgkJCQlpZiAoIXN0cm5jbXAob3B0ZXErMSwgInRjcCIsIDMpKQoJCQkJCXRjcCA9IDE7CgkJCQllbHNlIGlmICghc3RybmNtcChvcHRlcSsxLCAidWRwIiwgMykpCgkJCQkJdGNwID0gMDsKCQkJCWVsc2UKCQkJCQliYl9lcnJvcl9tc2coIndhcm5pbmc6IHVucmVjb2duaXplZCBwcm90bz0gb3B0aW9uIik7CgkJCQlicmVhazsKCQkJY2FzZSAxOTogLy8gIm5hbWxlbiIKCQkJCWlmIChuZnNfbW91bnRfdmVyc2lvbiA+PSAyKQoJCQkJCWRhdGEubmFtbGVuID0gdmFsOwoJCQkJZWxzZQoJCQkJCWJiX2Vycm9yX21zZygid2FybmluZzogb3B0aW9uIG5hbWxlbiBpcyBub3Qgc3VwcG9ydGVkXG4iKTsKCQkJCWJyZWFrOwoJCQljYXNlIDIwOiAvLyAiYWRkciIgLSBpZ25vcmUKCQkJCWJyZWFrOwoJCQlkZWZhdWx0OgoJCQkJYmJfZXJyb3JfbXNnKCJ1bmtub3duIG5mcyBtb3VudCBwYXJhbWV0ZXI6ICVzPSVkIiwgb3B0LCB2YWwpOwoJCQkJZ290byBmYWlsOwoJCQl9CgkJfQoJCWVsc2UgewoJCQljb25zdCBjaGFyICpjb25zdCBvcHRpb25zW10gPSB7CgkJCQkiYmciLAoJCQkJImZnIiwKCQkJCSJzb2Z0IiwKCQkJCSJoYXJkIiwKCQkJCSJpbnRyIiwKCQkJCSJwb3NpeCIsCgkJCQkiY3RvIiwKCQkJCSJhYyIsCgkJCQkidGNwIiwKCQkJCSJ1ZHAiLAoJCQkJImxvY2siLAoJCQkJTlVMTAoJCQl9OwoJCQlpbnQgdmFsID0gMTsKCQkJaWYgKCFzdHJuY21wKG9wdCwgIm5vIiwgMikpIHsKCQkJCXZhbCA9IDA7CgkJCQlvcHQgKz0gMjsKCQkJfQoJCQlzd2l0Y2ggKGluZGV4X2luX3N0cl9hcnJheShvcHRpb25zLCBvcHQpKSB7CgkJCWNhc2UgMDogLy8gImJnIgoJCQkJYmcgPSB2YWw7CgkJCQlicmVhazsKCQkJY2FzZSAxOiAvLyAiZmciCgkJCQliZyA9ICF2YWw7CgkJCQlicmVhazsKCQkJY2FzZSAyOiAvLyAic29mdCIKCQkJCXNvZnQgPSB2YWw7CgkJCQlicmVhazsKCQkJY2FzZSAzOiAvLyAiaGFyZCIKCQkJCXNvZnQgPSAhdmFsOwoJCQkJYnJlYWs7CgkJCWNhc2UgNDogLy8gImludHIiCgkJCQlpbnRyID0gdmFsOwoJCQkJYnJlYWs7CgkJCWNhc2UgNTogLy8gInBvc2l4IgoJCQkJcG9zaXggPSB2YWw7CgkJCQlicmVhazsKCQkJY2FzZSA2OiAvLyAiY3RvIgoJCQkJbm9jdG8gPSAhdmFsOwoJCQkJYnJlYWs7CgkJCWNhc2UgNzogLy8gImFjIgoJCQkJbm9hYyA9ICF2YWw7CgkJCQlicmVhazsKCQkJY2FzZSA4OiAvLyAidGNwIgoJCQkJdGNwID0gdmFsOwoJCQkJYnJlYWs7CgkJCWNhc2UgOTogLy8gInVkcCIKCQkJCXRjcCA9ICF2YWw7CgkJCQlicmVhazsKCQkJY2FzZSAxMDogLy8gImxvY2siCgkJCQlpZiAobmZzX21vdW50X3ZlcnNpb24gPj0gMykKCQkJCQlub2xvY2sgPSAhdmFsOwoJCQkJZWxzZQoJCQkJCWJiX2Vycm9yX21zZygid2FybmluZzogb3B0aW9uIG5vbG9jayBpcyBub3Qgc3VwcG9ydGVkIik7CgkJCQlicmVhazsKCQkJZGVmYXVsdDoKCQkJCWJiX2Vycm9yX21zZygidW5rbm93biBuZnMgbW91bnQgb3B0aW9uOiAlcyVzIiwgdmFsID8gIiIgOiAibm8iLCBvcHQpOwoJCQkJZ290byBmYWlsOwoJCQl9CgkJfQoJfQoJcHJvdG8gPSAodGNwKSA/IElQUFJPVE9fVENQIDogSVBQUk9UT19VRFA7CgoJZGF0YS5mbGFncyA9IChzb2Z0ID8gTkZTX01PVU5UX1NPRlQgOiAwKQoJCXwgKGludHIgPyBORlNfTU9VTlRfSU5UUiA6IDApCgkJfCAocG9zaXggPyBORlNfTU9VTlRfUE9TSVggOiAwKQoJCXwgKG5vY3RvID8gTkZTX01PVU5UX05PQ1RPIDogMCkKCQl8IChub2FjID8gTkZTX01PVU5UX05PQUMgOiAwKTsKCWlmIChuZnNfbW91bnRfdmVyc2lvbiA+PSAyKQoJCWRhdGEuZmxhZ3MgfD0gKHRjcCA/IE5GU19NT1VOVF9UQ1AgOiAwKTsKCWlmIChuZnNfbW91bnRfdmVyc2lvbiA+PSAzKQoJCWRhdGEuZmxhZ3MgfD0gKG5vbG9jayA/IE5GU19NT1VOVF9OT05MTSA6IDApOwoJaWYgKG5mc3ZlcnMgPiBNQVhfTkZTUFJPVCB8fCBtb3VudHZlcnMgPiBNQVhfTkZTUFJPVCkgewoJCWJiX2Vycm9yX21zZygiTkZTdiVkIG5vdCBzdXBwb3J0ZWQiLCBuZnN2ZXJzKTsKCQlnb3RvIGZhaWw7Cgl9CglpZiAobmZzdmVycyAmJiAhbW91bnR2ZXJzKQoJCW1vdW50dmVycyA9IChuZnN2ZXJzIDwgMykgPyAxIDogbmZzdmVyczsKCWlmIChuZnN2ZXJzICYmIG5mc3ZlcnMgPCBtb3VudHZlcnMpIHsKCQltb3VudHZlcnMgPSBuZnN2ZXJzOwoJfQoKCS8qIEFkanVzdCBvcHRpb25zIGlmIG5vbmUgc3BlY2lmaWVkICovCglpZiAoIWRhdGEudGltZW8pCgkJZGF0YS50aW1lbyA9IHRjcCA/IDcwIDogNzsKCglkYXRhLnZlcnNpb24gPSBuZnNfbW91bnRfdmVyc2lvbjsKCglpZiAodmZzZmxhZ3MgJiBNU19SRU1PVU5UKQoJCWdvdG8gZG9fbW91bnQ7CgoJLyoKCSAqIElmIHRoZSBwcmV2aW91cyBtb3VudCBvcGVyYXRpb24gb24gdGhlIHNhbWUgaG9zdCB3YXMKCSAqIGJhY2tncm91bmRlZCwgYW5kIHRoZSAiYmciIGZvciB0aGlzIG1vdW50IGlzIGFsc28gc2V0LAoJICogZ2l2ZSB1cCBpbW1lZGlhdGVseSwgdG8gYXZvaWQgdGhlIGluaXRpYWwgdGltZW91dC4KCSAqLwoJaWYgKGJnICYmIHdlX3Nhd190aGlzX2hvc3RfYmVmb3JlKGhvc3RuYW1lKSkgewoJCWRhZW1vbml6ZWQgPSBkYWVtb25pemUoKTsgLyogcGFyZW50IG9yIGVycm9yICovCgkJaWYgKGRhZW1vbml6ZWQgPD0gMCkgeyAvKiBwYXJlbnQgb3IgZXJyb3IgKi8KCQkJcmV0dmFsID0gLWRhZW1vbml6ZWQ7CgkJCWdvdG8gcmV0OwoJCX0KCX0KCgkvKiBjcmVhdGUgbW91bnQgZGFlbW9uIGNsaWVudCAqLwoJLyogU2VlIGlmIHRoZSBuZnMgaG9zdCA9IG1vdW50IGhvc3QuICovCglpZiAobW91bnRob3N0KSB7CgkJaWYgKG1vdW50aG9zdFswXSA+PSAnMCcgJiYgbW91bnRob3N0WzBdIDw9ICc5JykgewoJCQltb3VudF9zZXJ2ZXJfYWRkci5zaW5fZmFtaWx5ID0gQUZfSU5FVDsKCQkJbW91bnRfc2VydmVyX2FkZHIuc2luX2FkZHIuc19hZGRyID0gaW5ldF9hZGRyKGhvc3RuYW1lKTsKCQl9IGVsc2UgewoJCQlocCA9IGdldGhvc3RieW5hbWUobW91bnRob3N0KTsKCQkJaWYgKGhwID09IE5VTEwpIHsKCQkJCWJiX2hlcnJvcl9tc2coIiVzIiwgbW91bnRob3N0KTsKCQkJCWdvdG8gZmFpbDsKCQkJfSBlbHNlIHsKCQkJCWlmIChocC0+aF9sZW5ndGggPiBzaXplb2Yoc3RydWN0IGluX2FkZHIpKSB7CgkJCQkJYmJfZXJyb3JfbXNnKCJnb3QgYmFkIGhwLT5oX2xlbmd0aD8iKTsKCQkJCQlocC0+aF9sZW5ndGggPSBzaXplb2Yoc3RydWN0IGluX2FkZHIpOwoJCQkJfQoJCQkJbW91bnRfc2VydmVyX2FkZHIuc2luX2ZhbWlseSA9IEFGX0lORVQ7CgkJCQltZW1jcHkoJm1vdW50X3NlcnZlcl9hZGRyLnNpbl9hZGRyLAoJCQkJCQlocC0+aF9hZGRyLCBocC0+aF9sZW5ndGgpOwoJCQl9CgkJfQoJfQoKCS8qCgkgKiBUaGUgZm9sbG93aW5nIGxvb3AgaW1wbGVtZW50cyB0aGUgbW91bnQgcmV0cmllcy4gV2hlbiB0aGUgbW91bnQKCSAqIHRpbWVzIG91dCwgYW5kIHRoZSAiYmciIG9wdGlvbiBpcyBzZXQsIHdlIGJhY2tncm91bmQgb3Vyc2VsZgoJICogYW5kIGNvbnRpbnVlIHRyeWluZy4KCSAqCgkgKiBUaGUgY2FzZSB3aGVyZSB0aGUgbW91bnQgcG9pbnQgaXMgbm90IHByZXNlbnQgYW5kIHRoZSAiYmciCgkgKiBvcHRpb24gaXMgc2V0LCBpcyB0cmVhdGVkIGFzIGEgdGltZW91dC4gVGhpcyBpcyBkb25lIHRvCgkgKiBzdXBwb3J0IG5lc3RlZCBtb3VudHMuCgkgKgoJICogVGhlICJyZXRyeSIgY291bnQgc3BlY2lmaWVkIGJ5IHRoZSB1c2VyIGlzIHRoZSBudW1iZXIgb2YKCSAqIG1pbnV0ZXMgdG8gcmV0cnkgYmVmb3JlIGdpdmluZyB1cC4KCSAqLwoJewoJCXN0cnVjdCB0aW1ldmFsIHRvdGFsX3RpbWVvdXQ7CgkJc3RydWN0IHRpbWV2YWwgcmV0cnlfdGltZW91dDsKCQlzdHJ1Y3QgcG1hcCogcG1fbW50OwoJCXRpbWVfdCB0OwoJCXRpbWVfdCBwcmV2dDsKCQl0aW1lX3QgdGltZW91dDsKCgkJcmV0cnlfdGltZW91dC50dl9zZWMgPSAzOwoJCXJldHJ5X3RpbWVvdXQudHZfdXNlYyA9IDA7CgkJdG90YWxfdGltZW91dC50dl9zZWMgPSAyMDsKCQl0b3RhbF90aW1lb3V0LnR2X3VzZWMgPSAwOwoJCXRpbWVvdXQgPSB0aW1lKE5VTEwpICsgNjAgKiByZXRyeTsKCQlwcmV2dCA9IDA7CgkJdCA9IDMwOwpyZXRyeToKCQkvKiBiZSBjYXJlZnVsIG5vdCB0byB1c2UgdG9vIG1hbnkgQ1BVIGN5Y2xlcyAqLwoJCWlmICh0IC0gcHJldnQgPCAzMCkKCQkJc2xlZXAoMzApOwoKCQlwbV9tbnQgPSBnZXRfbW91bnRwb3J0KCZtb3VudF9zZXJ2ZXJfYWRkciwKCQkJCW1vdW50cHJvZywKCQkJCW1vdW50dmVycywKCQkJCXByb3RvLAoJCQkJbW91bnRwb3J0KTsKCQluZnN2ZXJzID0gKHBtX21udC0+cG1fdmVycyA8IDIpID8gMiA6IHBtX21udC0+cG1fdmVyczsKCgkJLyogY29udGFjdCB0aGUgbW91bnQgZGFlbW9uIHZpYSBUQ1AgKi8KCQltb3VudF9zZXJ2ZXJfYWRkci5zaW5fcG9ydCA9IGh0b25zKHBtX21udC0+cG1fcG9ydCk7CgkJbXNvY2sgPSBSUENfQU5ZU09DSzsKCgkJc3dpdGNoIChwbV9tbnQtPnBtX3Byb3QpIHsKCQljYXNlIElQUFJPVE9fVURQOgoJCQltY2xpZW50ID0gY2xudHVkcF9jcmVhdGUoJm1vdW50X3NlcnZlcl9hZGRyLAoJCQkJCQkgcG1fbW50LT5wbV9wcm9nLAoJCQkJCQkgcG1fbW50LT5wbV92ZXJzLAoJCQkJCQkgcmV0cnlfdGltZW91dCwKCQkJCQkJICZtc29jayk7CgkJCWlmIChtY2xpZW50KQoJCQkJYnJlYWs7CgkJCW1vdW50X3NlcnZlcl9hZGRyLnNpbl9wb3J0ID0gaHRvbnMocG1fbW50LT5wbV9wb3J0KTsKCQkJbXNvY2sgPSBSUENfQU5ZU09DSzsKCQljYXNlIElQUFJPVE9fVENQOgoJCQltY2xpZW50ID0gY2xudHRjcF9jcmVhdGUoJm1vdW50X3NlcnZlcl9hZGRyLAoJCQkJCQkgcG1fbW50LT5wbV9wcm9nLAoJCQkJCQkgcG1fbW50LT5wbV92ZXJzLAoJCQkJCQkgJm1zb2NrLCAwLCAwKTsKCQkJYnJlYWs7CgkJZGVmYXVsdDoKCQkJbWNsaWVudCA9IDA7CgkJfQoJCWlmICghbWNsaWVudCkgewoJCQlpZiAoIWRhZW1vbml6ZWQgJiYgcHJldnQgPT0gMCkKCQkJCWVycm9yX21zZ19ycGMoY2xudF9zcGNyZWF0ZWVycm9yKCIgIikpOwoJCX0gZWxzZSB7CgkJCWVudW0gY2xudF9zdGF0IGNsbnRfc3RhdDsKCQkJLyogdHJ5IHRvIG1vdW50IGhvc3RuYW1lOnBhdGhuYW1lICovCgkJCW1jbGllbnQtPmNsX2F1dGggPSBhdXRodW5peF9jcmVhdGVfZGVmYXVsdCgpOwoKCQkJLyogbWFrZSBwb2ludGVycyBpbiB4ZHJfbW91bnRyZXMzIE5VTEwgc28KCQkJICogdGhhdCB4ZHJfYXJyYXkgYWxsb2NhdGVzIG1lbW9yeSBmb3IgdXMKCQkJICovCgkJCW1lbXNldCgmc3RhdHVzLCAwLCBzaXplb2Yoc3RhdHVzKSk7CgoJCQlpZiAocG1fbW50LT5wbV92ZXJzID09IDMpCgkJCQljbG50X3N0YXQgPSBjbG50X2NhbGwobWNsaWVudCwgTU9VTlRQUk9DM19NTlQsCgkJCQkJICAgICAgKHhkcnByb2NfdCkgeGRyX2RpcnBhdGgsCgkJCQkJICAgICAgKGNhZGRyX3QpICZwYXRobmFtZSwKCQkJCQkgICAgICAoeGRycHJvY190KSB4ZHJfbW91bnRyZXMzLAoJCQkJCSAgICAgIChjYWRkcl90KSAmc3RhdHVzLAoJCQkJCSAgICAgIHRvdGFsX3RpbWVvdXQpOwoJCQllbHNlCgkJCQljbG50X3N0YXQgPSBjbG50X2NhbGwobWNsaWVudCwgTU9VTlRQUk9DX01OVCwKCQkJCQkgICAgICAoeGRycHJvY190KSB4ZHJfZGlycGF0aCwKCQkJCQkgICAgICAoY2FkZHJfdCkgJnBhdGhuYW1lLAoJCQkJCSAgICAgICh4ZHJwcm9jX3QpIHhkcl9maHN0YXR1cywKCQkJCQkgICAgICAoY2FkZHJfdCkgJnN0YXR1cywKCQkJCQkgICAgICB0b3RhbF90aW1lb3V0KTsKCgkJCWlmIChjbG50X3N0YXQgPT0gUlBDX1NVQ0NFU1MpCgkJCQlnb3RvIHByZXBhcmVfa2VybmVsX2RhdGE7IC8qIHdlJ3JlIGRvbmUgKi8KCQkJaWYgKGVycm5vICE9IEVDT05OUkVGVVNFRCkgewoJCQkJZXJyb3JfbXNnX3JwYyhjbG50X3NwZXJyb3IobWNsaWVudCwgIiAiKSk7CgkJCQlnb3RvIGZhaWw7CS8qIGRvbid0IHJldHJ5ICovCgkJCX0KCQkJLyogQ29ubmVjdGlvbiByZWZ1c2VkICovCgkJCWlmICghZGFlbW9uaXplZCAmJiBwcmV2dCA9PSAwKSAvKiBwcmludCBqdXN0IG9uY2UgKi8KCQkJCWVycm9yX21zZ19ycGMoY2xudF9zcGVycm9yKG1jbGllbnQsICIgIikpOwoJCQlhdXRoX2Rlc3Ryb3kobWNsaWVudC0+Y2xfYXV0aCk7CgkJCWNsbnRfZGVzdHJveShtY2xpZW50KTsKCQkJbWNsaWVudCA9IDA7CgkJCWNsb3NlKG1zb2NrKTsKCQl9CgoJCS8qIFRpbWVvdXQuIFdlIGFyZSBnb2luZyB0byByZXRyeS4uLiBtYXliZSAqLwoKCQlpZiAoIWJnKQoJCQlnb3RvIGZhaWw7CgkJaWYgKCFkYWVtb25pemVkKSB7CgkJCWRhZW1vbml6ZWQgPSBkYWVtb25pemUoKTsKCQkJaWYgKGRhZW1vbml6ZWQgPD0gMCkgeyAvKiBwYXJlbnQgb3IgZXJyb3IgKi8KCQkJCXJldHZhbCA9IC1kYWVtb25pemVkOwoJCQkJZ290byByZXQ7CgkJCX0KCQl9CgkJcHJldnQgPSB0OwoJCXQgPSB0aW1lKE5VTEwpOwoJCWlmICh0ID49IHRpbWVvdXQpCgkJCS8qIFRPRE8gZXJyb3IgbWVzc2FnZSAqLwoJCQlnb3RvIGZhaWw7CgoJCWdvdG8gcmV0cnk7Cgl9CgpwcmVwYXJlX2tlcm5lbF9kYXRhOgoKCWlmIChuZnN2ZXJzID09IDIpIHsKCQlpZiAoc3RhdHVzLm5mc3YyLmZoc19zdGF0dXMgIT0gMCkgewoJCQliYl9lcnJvcl9tc2coIiVzOiVzIGZhaWxlZCwgcmVhc29uIGdpdmVuIGJ5IHNlcnZlcjogJXMiLAoJCQkJaG9zdG5hbWUsIHBhdGhuYW1lLAoJCQkJbmZzX3N0cmVycm9yKHN0YXR1cy5uZnN2Mi5maHNfc3RhdHVzKSk7CgkJCWdvdG8gZmFpbDsKCQl9CgkJbWVtY3B5KGRhdGEucm9vdC5kYXRhLAoJCQkJKGNoYXIgKikgc3RhdHVzLm5mc3YyLmZoc3RhdHVzX3UuZmhzX2ZoYW5kbGUsCgkJCQlORlNfRkhTSVpFKTsKCQlkYXRhLnJvb3Quc2l6ZSA9IE5GU19GSFNJWkU7CgkJbWVtY3B5KGRhdGEub2xkX3Jvb3QuZGF0YSwKCQkJCShjaGFyICopIHN0YXR1cy5uZnN2Mi5maHN0YXR1c191LmZoc19maGFuZGxlLAoJCQkJTkZTX0ZIU0laRSk7Cgl9IGVsc2UgewoJCWZoYW5kbGUzICpteV9maGFuZGxlOwoJCWlmIChzdGF0dXMubmZzdjMuZmhzX3N0YXR1cyAhPSAwKSB7CgkJCWJiX2Vycm9yX21zZygiJXM6JXMgZmFpbGVkLCByZWFzb24gZ2l2ZW4gYnkgc2VydmVyOiAlcyIsCgkJCQlob3N0bmFtZSwgcGF0aG5hbWUsCgkJCQluZnNfc3RyZXJyb3Ioc3RhdHVzLm5mc3YzLmZoc19zdGF0dXMpKTsKCQkJZ290byBmYWlsOwoJCX0KCQlteV9maGFuZGxlID0gJnN0YXR1cy5uZnN2My5tb3VudHJlczNfdS5tb3VudGluZm8uZmhhbmRsZTsKCQltZW1zZXQoZGF0YS5vbGRfcm9vdC5kYXRhLCAwLCBORlNfRkhTSVpFKTsKCQltZW1zZXQoJmRhdGEucm9vdCwgMCwgc2l6ZW9mKGRhdGEucm9vdCkpOwoJCWRhdGEucm9vdC5zaXplID0gbXlfZmhhbmRsZS0+ZmhhbmRsZTNfbGVuOwoJCW1lbWNweShkYXRhLnJvb3QuZGF0YSwKCQkJCShjaGFyICopIG15X2ZoYW5kbGUtPmZoYW5kbGUzX3ZhbCwKCQkJCW15X2ZoYW5kbGUtPmZoYW5kbGUzX2xlbik7CgoJCWRhdGEuZmxhZ3MgfD0gTkZTX01PVU5UX1ZFUjM7Cgl9CgoJLyogY3JlYXRlIG5mcyBzb2NrZXQgZm9yIGtlcm5lbCAqLwoKCWlmICh0Y3ApIHsKCQlpZiAobmZzX21vdW50X3ZlcnNpb24gPCAzKSB7CgkJCWJiX2Vycm9yX21zZygiTkZTIG92ZXIgVENQIGlzIG5vdCBzdXBwb3J0ZWQiKTsKCQkJZ290byBmYWlsOwoJCX0KCQlmc29jayA9IHNvY2tldChBRl9JTkVULCBTT0NLX1NUUkVBTSwgSVBQUk9UT19UQ1ApOwoJfSBlbHNlCgkJZnNvY2sgPSBzb2NrZXQoQUZfSU5FVCwgU09DS19ER1JBTSwgSVBQUk9UT19VRFApOwoJaWYgKGZzb2NrIDwgMCkgewoJCWJiX3BlcnJvcl9tc2coIm5mcyBzb2NrZXQiKTsKCQlnb3RvIGZhaWw7Cgl9CglpZiAoYmluZHJlc3Zwb3J0KGZzb2NrLCAwKSA8IDApIHsKCQliYl9wZXJyb3JfbXNnKCJuZnMgYmluZHJlc3Zwb3J0Iik7CgkJZ290byBmYWlsOwoJfQoJaWYgKHBvcnQgPT0gMCkgewoJCXNlcnZlcl9hZGRyLnNpbl9wb3J0ID0gUE1BUFBPUlQ7CgkJcG9ydCA9IHBtYXBfZ2V0cG9ydCgmc2VydmVyX2FkZHIsIG5mc3Byb2csIG5mc3ZlcnMsCgkJCQkJdGNwID8gSVBQUk9UT19UQ1AgOiBJUFBST1RPX1VEUCk7CgkJaWYgKHBvcnQgPT0gMCkKCQkJcG9ydCA9IE5GU19QT1JUOwoJfQoJc2VydmVyX2FkZHIuc2luX3BvcnQgPSBodG9ucyhwb3J0KTsKCgkvKiBwcmVwYXJlIGRhdGEgc3RydWN0dXJlIGZvciBrZXJuZWwgKi8KCglkYXRhLmZkID0gZnNvY2s7CgltZW1jcHkoKGNoYXIgKikgJmRhdGEuYWRkciwgKGNoYXIgKikgJnNlcnZlcl9hZGRyLCBzaXplb2YoZGF0YS5hZGRyKSk7CglzdHJuY3B5KGRhdGEuaG9zdG5hbWUsIGhvc3RuYW1lLCBzaXplb2YoZGF0YS5ob3N0bmFtZSkpOwoKCS8qIGNsZWFuIHVwICovCgoJYXV0aF9kZXN0cm95KG1jbGllbnQtPmNsX2F1dGgpOwoJY2xudF9kZXN0cm95KG1jbGllbnQpOwoJY2xvc2UobXNvY2spOwoKCWlmIChiZykgewoJCS8qIFdlIG11c3Qgd2FpdCB1bnRpbCBtb3VudCBkaXJlY3RvcnkgaXMgYXZhaWxhYmxlICovCgkJc3RydWN0IHN0YXQgc3RhdGJ1ZjsKCQlpbnQgZGVsYXkgPSAxOwoJCXdoaWxlIChzdGF0KG1wLT5tbnRfZGlyLCAmc3RhdGJ1ZikgPT0gLTEpIHsKCQkJaWYgKCFkYWVtb25pemVkKSB7CgkJCQlkYWVtb25pemVkID0gZGFlbW9uaXplKCk7CgkJCQlpZiAoZGFlbW9uaXplZCA8PSAwKSB7IC8qIHBhcmVudCBvciBlcnJvciAqLwoJCQkJCXJldHZhbCA9IC1kYWVtb25pemVkOwoJCQkJCWdvdG8gcmV0OwoJCQkJfQoJCQl9CgkJCXNsZWVwKGRlbGF5KTsJLyogMSwgMiwgNCwgOCwgMTYsIDMwLCAuLi4gKi8KCQkJZGVsYXkgKj0gMjsKCQkJaWYgKGRlbGF5ID4gMzApCgkJCQlkZWxheSA9IDMwOwoJCX0KCX0KCmRvX21vdW50OiAvKiBwZXJmb3JtIGFjdHVhbCBtb3VudCAqLwoKCW1wLT5tbnRfdHlwZSA9ICJuZnMiOwoJcmV0dmFsID0gbW91bnRfaXRfbm93KG1wLCB2ZnNmbGFncywgKGNoYXIqKSZkYXRhKTsKCWdvdG8gcmV0OwoKZmFpbDoJLyogYWJvcnQgKi8KCglpZiAobXNvY2sgIT0gLTEpIHsKCQlpZiAobWNsaWVudCkgewoJCQlhdXRoX2Rlc3Ryb3kobWNsaWVudC0+Y2xfYXV0aCk7CgkJCWNsbnRfZGVzdHJveShtY2xpZW50KTsKCQl9CgkJY2xvc2UobXNvY2spOwoJfQoJaWYgKGZzb2NrICE9IC0xKQoJCWNsb3NlKGZzb2NrKTsKCnJldDoKCWZyZWUoaG9zdG5hbWUpOwoJZnJlZShtb3VudGhvc3QpOwoJZnJlZShmaWx0ZXJvcHRzKTsKCXJldHVybiByZXR2YWw7Cn0KCiNlbHNlIC8qICFFTkFCTEVfRkVBVFVSRV9NT1VOVF9ORlMgKi8KCi8qIE5ldmVyIGNhbGxlZC4gQ2FsbCBzaG91bGQgYmUgb3B0aW1pemVkIG91dC4gKi8KaW50IG5mc21vdW50KHN0cnVjdCBtbnRlbnQgKm1wLCBpbnQgdmZzZmxhZ3MsIGNoYXIgKmZpbHRlcm9wdHMpOwoKI2VuZGlmIC8qICFFTkFCTEVfRkVBVFVSRV9NT1VOVF9ORlMgKi8KCi8vIE1vdW50IG9uZSBkaXJlY3RvcnkuICBIYW5kbGVzIENJRlMsIE5GUywgbG9vcGJhY2ssIGF1dG9iaW5kLCBhbmQgZmlsZXN5c3RlbQovLyB0eXBlIGRldGVjdGlvbi4gIFJldHVybnMgMCBmb3Igc3VjY2Vzcywgbm9uemVybyBmb3IgZmFpbHVyZS4KLy8gTkI6IG1wLT54eHggZmllbGRzIG1heSBiZSB0cmFzaGVkIG9uIGV4aXQKc3RhdGljIGludCBzaW5nbGVtb3VudChzdHJ1Y3QgbW50ZW50ICptcCwgaW50IGlnbm9yZV9idXN5KQp7CglpbnQgcmMgPSAtMSwgdmZzZmxhZ3M7CgljaGFyICpsb29wRmlsZSA9IDAsICpmaWx0ZXJvcHRzID0gMDsKCWxsaXN0X3QgKmZsID0gMDsKCXN0cnVjdCBzdGF0IHN0OwoKCXZmc2ZsYWdzID0gcGFyc2VfbW91bnRfb3B0aW9ucyhtcC0+bW50X29wdHMsICZmaWx0ZXJvcHRzKTsKCgkvLyBUcmVhdCBmc3R5cGUgImF1dG8iIGFzIHVuc3BlY2lmaWVkLgoKCWlmIChtcC0+bW50X3R5cGUgJiYgIXN0cmNtcChtcC0+bW50X3R5cGUsImF1dG8iKSkgbXAtPm1udF90eXBlID0gMDsKCgkvLyBNaWdodCB0aGlzIGJlIGFuIENJRlMgZmlsZXN5c3RlbT8KCglpZiAoRU5BQkxFX0ZFQVRVUkVfTU9VTlRfQ0lGUyAmJgoJCSghbXAtPm1udF90eXBlIHx8ICFzdHJjbXAobXAtPm1udF90eXBlLCJjaWZzIikpICYmCgkJKG1wLT5tbnRfZnNuYW1lWzBdPT1tcC0+bW50X2ZzbmFtZVsxXSAmJiAobXAtPm1udF9mc25hbWVbMF09PScvJyB8fCBtcC0+bW50X2ZzbmFtZVswXT09J1xcJykpKQoJewoJCXN0cnVjdCBob3N0ZW50ICpoZTsKCQljaGFyIGlwWzMyXSwgKnM7CgoJCXJjID0gMTsKCQkvLyBSZXBsYWNlICcvJyB3aXRoICdcJyBhbmQgdmVyaWZ5IHRoYXQgdW5jIHBvaW50cyB0byAiLy9zZXJ2ZXIvc2hhcmUiLgoKCQlmb3IgKHMgPSBtcC0+bW50X2ZzbmFtZTsgKnM7ICsrcykKCQkJaWYgKCpzID09ICcvJykgKnMgPSAnXFwnOwoKCQkvLyBnZXQgc2VydmVyIElQCgoJCXMgPSBzdHJyY2hyKG1wLT5tbnRfZnNuYW1lLCAnXFwnKTsKCQlpZiAocyA9PSBtcC0+bW50X2ZzbmFtZSsxKSBnb3RvIHJlcG9ydF9lcnJvcjsKCQkqcyA9IDA7CgkJaGUgPSBnZXRob3N0YnluYW1lKG1wLT5tbnRfZnNuYW1lKzIpOwoJCSpzID0gJ1xcJzsKCQlpZiAoIWhlKSBnb3RvIHJlcG9ydF9lcnJvcjsKCgkJLy8gSW5zZXJ0IGlwPS4uLiBvcHRpb24gaW50byBzdHJpbmcgZmxhZ3MuICAoTk9URTogQWRkIElQdjYgc3VwcG9ydC4pCgoJCXNwcmludGYoaXAsICJpcD0lZC4lZC4lZC4lZCIsIGhlLT5oX2FkZHJbMF0sIGhlLT5oX2FkZHJbMV0sCgkJCQloZS0+aF9hZGRyWzJdLCBoZS0+aF9hZGRyWzNdKTsKCQlwYXJzZV9tb3VudF9vcHRpb25zKGlwLCAmZmlsdGVyb3B0cyk7CgoJCS8vIGNvbXBvc2UgbmV3IHVuYyAnXFxzZXJ2ZXItaXBcc2hhcmUnCgoJCW1wLT5tbnRfZnNuYW1lID0geGFzcHJpbnRmKCJcXFxcJXMlcyIsIGlwKzMsCgkJCQkJc3RyY2hyKG1wLT5tbnRfZnNuYW1lKzIsJ1xcJykpOwoKCQkvLyBsb2NrIGlzIHJlcXVpcmVkCgkJdmZzZmxhZ3MgfD0gTVNfTUFORExPQ0s7CgoJCW1wLT5tbnRfdHlwZSA9ICJjaWZzIjsKCQlyYyA9IG1vdW50X2l0X25vdyhtcCwgdmZzZmxhZ3MsIGZpbHRlcm9wdHMpOwoJCWlmIChFTkFCTEVfRkVBVFVSRV9DTEVBTl9VUCkgZnJlZShtcC0+bW50X2ZzbmFtZSk7CgkJZ290byByZXBvcnRfZXJyb3I7Cgl9CgoJLy8gTWlnaHQgdGhpcyBiZSBhbiBORlMgZmlsZXN5c3RlbT8KCglpZiAoRU5BQkxFX0ZFQVRVUkVfTU9VTlRfTkZTICYmCgkJKCFtcC0+bW50X3R5cGUgfHwgIXN0cmNtcChtcC0+bW50X3R5cGUsIm5mcyIpKSAmJgoJCXN0cmNocihtcC0+bW50X2ZzbmFtZSwgJzonKSAhPSBOVUxMKQoJewoJCXJjID0gbmZzbW91bnQobXAsIHZmc2ZsYWdzLCBmaWx0ZXJvcHRzKTsKCQlnb3RvIHJlcG9ydF9lcnJvcjsKCX0KCgkvLyBMb29rIGF0IHRoZSBmaWxlLiAgKE5vdCBmb3VuZCBpc24ndCBhIGZhaWx1cmUgZm9yIHJlbW91bnQsIG9yIGZvcgoJLy8gYSBzeW50aGV0aWMgZmlsZXN5c3RlbSBsaWtlIHByb2Mgb3Igc3lzZnMuKQoKCWlmICghbHN0YXQobXAtPm1udF9mc25hbWUsICZzdCkgJiYgISh2ZnNmbGFncyAmIChNU19SRU1PVU5UIHwgTVNfQklORCB8IE1TX01PVkUpKSkKCXsKCQkvLyBEbyB3ZSBuZWVkIHRvIGFsbG9jYXRlIGEgbG9vcGJhY2sgZGV2aWNlIGZvciBpdD8KCgkJaWYgKEVOQUJMRV9GRUFUVVJFX01PVU5UX0xPT1AgJiYgU19JU1JFRyhzdC5zdF9tb2RlKSkgewoJCQlsb29wRmlsZSA9IGJiX3NpbXBsaWZ5X3BhdGgobXAtPm1udF9mc25hbWUpOwoJCQltcC0+bW50X2ZzbmFtZSA9IDA7CgkJCXN3aXRjaCAoc2V0X2xvb3AoJihtcC0+bW50X2ZzbmFtZSksIGxvb3BGaWxlLCAwKSkgewoJCQljYXNlIDA6CgkJCWNhc2UgMToKCQkJCWJyZWFrOwoJCQlkZWZhdWx0OgoJCQkJYmJfZXJyb3JfbXNnKCBlcnJubyA9PSBFUEVSTSB8fCBlcnJubyA9PSBFQUNDRVMKCQkJCQk/IGJiX21zZ19wZXJtX2RlbmllZF9hcmVfeW91X3Jvb3QKCQkJCQk6ICJjYW5ub3Qgc2V0dXAgbG9vcCBkZXZpY2UiKTsKCQkJCXJldHVybiBlcnJubzsKCQkJfQoKCQkvLyBBdXRvZGV0ZWN0IGJpbmQgbW91bnRzCgoJCX0gZWxzZSBpZiAoU19JU0RJUihzdC5zdF9tb2RlKSAmJiAhbXAtPm1udF90eXBlKQoJCQl2ZnNmbGFncyB8PSBNU19CSU5EOwoJfQoKCS8qIElmIHdlIGtub3cgdGhlIGZzdHlwZSAob3IgZG9uJ3QgbmVlZCB0byksIGp1bXAgc3RyYWlnaHQKCSAqIHRvIHRoZSBhY3R1YWwgbW91bnQuICovCgoJaWYgKG1wLT5tbnRfdHlwZSB8fCAodmZzZmxhZ3MgJiAoTVNfUkVNT1VOVCB8IE1TX0JJTkQgfCBNU19NT1ZFKSkpCgkJcmMgPSBtb3VudF9pdF9ub3cobXAsIHZmc2ZsYWdzLCBmaWx0ZXJvcHRzKTsKCgkvLyBMb29wIHRocm91Z2ggZmlsZXN5c3RlbSB0eXBlcyB1bnRpbCBtb3VudCBzdWNjZWVkcyBvciB3ZSBydW4gb3V0CgoJZWxzZSB7CgoJCS8qIEluaXRpYWxpemUgbGlzdCBvZiBibG9jayBiYWNrZWQgZmlsZXN5c3RlbXMuICBUaGlzIGhhcyB0byBiZQoJCSAqIGRvbmUgaGVyZSBzbyB0aGF0IGR1cmluZyAibW91bnQgLWEiLCBtb3VudHMgYWZ0ZXIgL3Byb2Mgc2hvd3MgdXAKCQkgKiBjYW4gYXV0b2RldGVjdC4gKi8KCgkJaWYgKCFmc2xpc3QpIHsKCQkJZnNsaXN0ID0gZ2V0X2Jsb2NrX2JhY2tlZF9maWxlc3lzdGVtcygpOwoJCQlpZiAoRU5BQkxFX0ZFQVRVUkVfQ0xFQU5fVVAgJiYgZnNsaXN0KQoJCQkJYXRleGl0KGRlbGV0ZV9ibG9ja19iYWNrZWRfZmlsZXN5c3RlbXMpOwoJCX0KCgkJZm9yIChmbCA9IGZzbGlzdDsgZmw7IGZsID0gZmwtPmxpbmspIHsKCQkJbXAtPm1udF90eXBlID0gZmwtPmRhdGE7CgkJCXJjID0gbW91bnRfaXRfbm93KG1wLCB2ZnNmbGFncywgZmlsdGVyb3B0cyk7CgkJCWlmICghcmMpIGJyZWFrOwoJCX0KCX0KCgkvLyBJZiBtb3VudCBmYWlsZWQsIGNsZWFuIHVwIGxvb3AgZmlsZSAoaWYgYW55KS4KCglpZiAoRU5BQkxFX0ZFQVRVUkVfTU9VTlRfTE9PUCAmJiByYyAmJiBsb29wRmlsZSkgewoJCWRlbF9sb29wKG1wLT5tbnRfZnNuYW1lKTsKCQlpZiAoRU5BQkxFX0ZFQVRVUkVfQ0xFQU5fVVApIHsKCQkJZnJlZShsb29wRmlsZSk7CgkJCWZyZWUobXAtPm1udF9mc25hbWUpOwoJCX0KCX0KCnJlcG9ydF9lcnJvcjoKCWlmIChFTkFCTEVfRkVBVFVSRV9DTEVBTl9VUCkgZnJlZShmaWx0ZXJvcHRzKTsKCglpZiAocmMgJiYgZXJybm8gPT0gRUJVU1kgJiYgaWdub3JlX2J1c3kpIHJjID0gMDsKCWlmIChyYyA8IDApCgkJLyogcGVycm9yIGhlcmUgc29tZXRpbWVzIHNheXMgIm1vdW50aW5nIC4uLiBvbiAuLi4gZmFpbGVkOiBTdWNjZXNzIiAqLwoJCWJiX2Vycm9yX21zZygibW91bnRpbmcgJXMgb24gJXMgZmFpbGVkIiwgbXAtPm1udF9mc25hbWUsIG1wLT5tbnRfZGlyKTsKCglyZXR1cm4gcmM7Cn0KCi8vIFBhcnNlIG9wdGlvbnMsIGlmIG5lY2Vzc2FyeSBwYXJzZSBmc3RhYi9tdGFiLCBhbmQgY2FsbCBzaW5nbGVtb3VudCBmb3IKLy8gZWFjaCBkaXJlY3RvcnkgdG8gYmUgbW91bnRlZC4KCmNvbnN0IGNoYXIgbXVzdF9iZV9yb290W10gPSAieW91IG11c3QgYmUgcm9vdCI7CgppbnQgbW91bnRfbWFpbihpbnQgYXJnYywgY2hhciAqKmFyZ3YpCnsKCWVudW0geyBPUFRfQUxMID0gMHgxMCB9OwoKCWNoYXIgKmNtZG9wdHMgPSB4c3RyZHVwKCIiKSwgKmZzdHlwZT0wLCAqc3RvcmFnZV9wYXRoPTA7CgljaGFyICpvcHRfbzsKCWNvbnN0IGNoYXIgKmZzdGFibmFtZTsKCUZJTEUgKmZzdGFiOwoJaW50IGksIGosIHJjID0gMDsKCXVuc2lnbmVkIG9wdDsKCXN0cnVjdCBtbnRlbnQgbXRwYWlyWzJdLCAqbXRjdXIgPSBtdHBhaXI7CglTS0lQX0RFU0tUT1AoY29uc3QgaW50IG5vbnJvb3QgPSAwOykKCVVTRV9ERVNLVE9QKCBpbnQgbm9ucm9vdCA9IChnZXR1aWQoKSAhPSAwKTspCgoJLyogcGFyc2UgbG9uZyBvcHRpb25zLCBsaWtlIC0tYmluZCBhbmQgLS1tb3ZlLiAgTm90ZSB0aGF0IC1vIG9wdGlvbgoJICogYW5kIC0tb3B0aW9uIGFyZSBzeW5vbnltb3VzLiAgWWVzLCB0aGlzIG1lYW5zIC0tcmVtb3VudCxydyB3b3Jrcy4gKi8KCglmb3IgKGkgPSBqID0gMDsgaSA8IGFyZ2M7IGkrKykgewoJCWlmIChhcmd2W2ldWzBdID09ICctJyAmJiBhcmd2W2ldWzFdID09ICctJykgewoJCQlhcHBlbmRfbW91bnRfb3B0aW9ucygmY21kb3B0cywgYXJndltpXSsyKTsKCQl9IGVsc2UgYXJndltqKytdID0gYXJndltpXTsKCX0KCWFyZ3Zbal0gPSAwOwoJYXJnYyA9IGo7CgoJLy8gUGFyc2UgcmVtYWluaW5nIG9wdGlvbnMKCglvcHQgPSBnZXRvcHQzMihhcmdjLCBhcmd2LCAibzp0OnJ3YW5mdnMiLCAmb3B0X28sICZmc3R5cGUpOwoJaWYgKG9wdCAmIDB4MSkgYXBwZW5kX21vdW50X29wdGlvbnMoJmNtZG9wdHMsIG9wdF9vKTsgLy8gLW8KCS8vaWYgKG9wdCAmIDB4MikgLy8gLXQKCWlmIChvcHQgJiAweDQpIGFwcGVuZF9tb3VudF9vcHRpb25zKCZjbWRvcHRzLCAicm8iKTsgLy8gLXIKCWlmIChvcHQgJiAweDgpIGFwcGVuZF9tb3VudF9vcHRpb25zKCZjbWRvcHRzLCAicnciKTsgLy8gLXcKCS8vaWYgKG9wdCAmIDB4MTApIC8vIC1hCglpZiAob3B0ICYgMHgyMCkgVVNFX0ZFQVRVUkVfTVRBQl9TVVBQT1JUKHVzZU10YWIgPSAwKTsgLy8gLW4KCWlmIChvcHQgJiAweDQwKSBVU0VfRkVBVFVSRV9NVEFCX1NVUFBPUlQoZmFrZUl0ID0gMSk7IC8vIC1mCgkvL2lmIChvcHQgJiAweDgwKSAvLyAtdjogdmVyYm9zZSAoaWdub3JlKQoJLy9pZiAob3B0ICYgMHgxMDApIC8vIC1zOiBzbG9wcHkgKGlnbm9yZSkKCWFyZ3YgKz0gb3B0aW5kOwoJYXJnYyAtPSBvcHRpbmQ7CgoJLy8gVGhyZWUgb3IgbW9yZSBub24tb3B0aW9uIGFyZ3VtZW50cz8gIERpZSB3aXRoIGEgdXNhZ2UgbWVzc2FnZS4KCglpZiAoYXJnYyA+IDIpIGJiX3Nob3dfdXNhZ2UoKTsKCgkvLyBJZiB3ZSBoYXZlIG5vIGFyZ3VtZW50cywgc2hvdyBjdXJyZW50bHkgbW91bnRlZCBmaWxlc3lzdGVtcwoKCWlmICghYXJnYykgewoJCWlmICghKG9wdCAmIE9QVF9BTEwpKSB7CgkJCUZJTEUgKm1vdW50VGFibGUgPSBzZXRtbnRlbnQoYmJfcGF0aF9tdGFiX2ZpbGUsICJyIik7CgoJCQlpZiAoIW1vdW50VGFibGUpIGJiX2Vycm9yX21zZ19hbmRfZGllKCJubyAlcyIsIGJiX3BhdGhfbXRhYl9maWxlKTsKCgkJCXdoaWxlIChnZXRtbnRlbnRfcihtb3VudFRhYmxlLCBtdHBhaXIsIGJiX2NvbW1vbl9idWZzaXoxLAoJCQkJCQkJCXNpemVvZihiYl9jb21tb25fYnVmc2l6MSkpKQoJCQl7CgkJCQkvLyBEb24ndCBzaG93IHJvb3Rmcy4gRklYTUU6IHdoeT8/CgkJCQlpZiAoIXN0cmNtcChtdHBhaXItPm1udF9mc25hbWUsICJyb290ZnMiKSkgY29udGludWU7CgoJCQkJaWYgKCFmc3R5cGUgfHwgIXN0cmNtcChtdHBhaXItPm1udF90eXBlLCBmc3R5cGUpKQoJCQkJCXByaW50ZigiJXMgb24gJXMgdHlwZSAlcyAoJXMpXG4iLCBtdHBhaXItPm1udF9mc25hbWUsCgkJCQkJCQltdHBhaXItPm1udF9kaXIsIG10cGFpci0+bW50X3R5cGUsCgkJCQkJCQltdHBhaXItPm1udF9vcHRzKTsKCQkJfQoJCQlpZiAoRU5BQkxFX0ZFQVRVUkVfQ0xFQU5fVVApIGVuZG1udGVudChtb3VudFRhYmxlKTsKCQkJcmV0dXJuIEVYSVRfU1VDQ0VTUzsKCQl9Cgl9IGVsc2Ugc3RvcmFnZV9wYXRoID0gYmJfc2ltcGxpZnlfcGF0aChhcmd2WzBdKTsKCgkvLyBXaGVuIHdlIGhhdmUgdHdvIGFyZ3VtZW50cywgdGhlIHNlY29uZCBpcyB0aGUgZGlyZWN0b3J5IGFuZCB3ZSBjYW4KCS8vIHNraXAgbG9va2luZyBhdCBmc3RhYiBlbnRpcmVseS4gIFdlIGNhbiBhbHdheXMgYWJzcGF0aCgpIHRoZSBkaXJlY3RvcnkKCS8vIGFyZ3VtZW50IHdoZW4gd2UgZ2V0IGl0LgoKCWlmIChhcmdjID09IDIpIHsKCQlpZiAobm9ucm9vdCkKCQkJYmJfZXJyb3JfbXNnX2FuZF9kaWUobXVzdF9iZV9yb290KTsKCQltdHBhaXItPm1udF9mc25hbWUgPSBhcmd2WzBdOwoJCW10cGFpci0+bW50X2RpciA9IGFyZ3ZbMV07CgkJbXRwYWlyLT5tbnRfdHlwZSA9IGZzdHlwZTsKCQltdHBhaXItPm1udF9vcHRzID0gY21kb3B0czsKCQlyYyA9IHNpbmdsZW1vdW50KG10cGFpciwgMCk7CgkJZ290byBjbGVhbl91cDsKCX0KCglpID0gcGFyc2VfbW91bnRfb3B0aW9ucyhjbWRvcHRzLCAwKTsKCWlmIChub25yb290ICYmIChpICYgfk1TX1NJTEVOVCkpIC8vIE5vbi1yb290IHVzZXJzIGNhbm5vdCBzcGVjaWZ5IGZsYWdzCgkJYmJfZXJyb3JfbXNnX2FuZF9kaWUobXVzdF9iZV9yb290KTsKCgkvLyBJZiB3ZSBoYXZlIGEgc2hhcmVkIHN1YnRyZWUgZmxhZywgZG9uJ3Qgd29ycnkgYWJvdXQgZnN0YWIgb3IgbXRhYi4KCglpZiAoRU5BQkxFX0ZFQVRVUkVfTU9VTlRfRkxBR1MgJiYKCQkJKGkgJiAoTVNfU0hBUkVEIHwgTVNfUFJJVkFURSB8IE1TX1NMQVZFIHwgTVNfVU5CSU5EQUJMRSkpKQoJewoJCXJjID0gbW91bnQoIiIsIGFyZ3ZbMF0sICIiLCBpLCAiIik7CgkJaWYgKHJjKSBiYl9wZXJyb3JfbXNnX2FuZF9kaWUoIiVzIiwgYXJndlswXSk7CgkJZ290byBjbGVhbl91cDsKCX0KCgkvLyBPcGVuIGVpdGhlciBmc3RhYiBvciBtdGFiCgoJZnN0YWJuYW1lID0gIi9ldGMvZnN0YWIiOwoJaWYgKGkgJiBNU19SRU1PVU5UKSB7CgkJZnN0YWJuYW1lID0gYmJfcGF0aF9tdGFiX2ZpbGU7Cgl9Cglmc3RhYiA9IHNldG1udGVudChmc3RhYm5hbWUsICJyIik7CglpZiAoIWZzdGFiKQoJCWJiX3BlcnJvcl9tc2dfYW5kX2RpZSgiY2Fubm90IHJlYWQgJXMiLCBmc3RhYm5hbWUpOwoKCS8vIExvb3AgdGhyb3VnaCBlbnRyaWVzIHVudGlsIHdlIGZpbmQgd2hhdCB3ZSdyZSBsb29raW5nIGZvci4KCgltZW1zZXQobXRwYWlyLCAwLCBzaXplb2YobXRwYWlyKSk7Cglmb3IgKDs7KSB7CgkJc3RydWN0IG1udGVudCAqbXRuZXh0ID0gKG10Y3VyPT1tdHBhaXIgPyBtdHBhaXIrMSA6IG10cGFpcik7CgoJCS8vIEdldCBuZXh0IGZzdGFiIGVudHJ5CgoJCWlmICghZ2V0bW50ZW50X3IoZnN0YWIsIG10Y3VyLCBiYl9jb21tb25fYnVmc2l6MQoJCQkJCSsgKG10Y3VyPT1tdHBhaXIgPyBzaXplb2YoYmJfY29tbW9uX2J1ZnNpejEpLzIgOiAwKSwKCQkJCXNpemVvZihiYl9jb21tb25fYnVmc2l6MSkvMikpCgkJewoJCQkvLyBXZXJlIHdlIGxvb2tpbmcgZm9yIHNvbWV0aGluZyBzcGVjaWZpYz8KCgkJCWlmIChhcmdjKSB7CgoJCQkJLy8gSWYgd2UgZGlkbid0IGZpbmQgYW55dGhpbmcsIGNvbXBsYWluLgoKCQkJCWlmICghbXRuZXh0LT5tbnRfZnNuYW1lKQoJCQkJCWJiX2Vycm9yX21zZ19hbmRfZGllKCJjYW4ndCBmaW5kICVzIGluICVzIiwKCQkJCQkJYXJndlswXSwgZnN0YWJuYW1lKTsKCgkJCQltdGN1ciA9IG10bmV4dDsKCQkJCWlmIChub25yb290KSB7CgkJCQkJLy8gZnN0YWIgbXVzdCBoYXZlICJ1c2VycyIgb3IgInVzZXIiCgkJCQkJaWYgKCEocGFyc2VfbW91bnRfb3B0aW9ucyhtdGN1ci0+bW50X29wdHMsIDApICYgTU9VTlRfVVNFUlMpKQoJCQkJCQliYl9lcnJvcl9tc2dfYW5kX2RpZShtdXN0X2JlX3Jvb3QpOwoJCQkJfQoKCQkJCS8vIE1vdW50IHRoZSBsYXN0IHRoaW5nIHdlIGZvdW5kLgoKCQkJCW10Y3VyLT5tbnRfb3B0cyA9IHhzdHJkdXAobXRjdXItPm1udF9vcHRzKTsKCQkJCWFwcGVuZF9tb3VudF9vcHRpb25zKCYobXRjdXItPm1udF9vcHRzKSwgY21kb3B0cyk7CgkJCQlyYyA9IHNpbmdsZW1vdW50KG10Y3VyLCAwKTsKCQkJCWZyZWUobXRjdXItPm1udF9vcHRzKTsKCQkJfQoJCQlnb3RvIGNsZWFuX3VwOwoJCX0KCgkJLyogSWYgd2UncmUgdHJ5aW5nIHRvIG1vdW50IHNvbWV0aGluZyBzcGVjaWZpYyBhbmQgdGhpcyBpc24ndCBpdCwKCQkgKiBza2lwIGl0LiAgTm90ZSB3ZSBtdXN0IG1hdGNoIGJvdGggdGhlIGV4YWN0IHRleHQgaW4gZnN0YWIgKGFsYQoJCSAqICJwcm9jIikgb3IgYSBmdWxsIHBhdGggZnJvbSByb290ICovCgoJCWlmIChhcmdjKSB7CgoJCQkvLyBJcyB0aGlzIHdoYXQgd2UncmUgbG9va2luZyBmb3I/CgoJCQlpZiAoc3RyY21wKGFyZ3ZbMF0sIG10Y3VyLT5tbnRfZnNuYW1lKSAmJgoJCQkgICBzdHJjbXAoc3RvcmFnZV9wYXRoLCBtdGN1ci0+bW50X2ZzbmFtZSkgJiYKCQkJICAgc3RyY21wKGFyZ3ZbMF0sIG10Y3VyLT5tbnRfZGlyKSAmJgoJCQkgICBzdHJjbXAoc3RvcmFnZV9wYXRoLCBtdGN1ci0+bW50X2RpcikpIGNvbnRpbnVlOwoKCQkJLy8gUmVtZW1iZXIgdGhpcyBlbnRyeS4gIFNvbWV0aGluZyBsYXRlciBtYXkgaGF2ZSBvdmVybW91bnRlZAoJCQkvLyBpdCwgYW5kIHdlIHdhbnQgdGhlIF9sYXN0XyBtYXRjaC4KCgkJCW10Y3VyID0gbXRuZXh0OwoKCQkvLyBJZiB3ZSdyZSBtb3VudGluZyBhbGwuCgoJCX0gZWxzZSB7CgkJCS8vIERvIHdlIG5lZWQgdG8gbWF0Y2ggYSBmaWxlc3lzdGVtIHR5cGU/CgkJCS8vIFRPRE86IHN1cHBvcnQgIi10IHR5cGUxLHR5cGUyIjsgIi10IG5vdHlwZTEsdHlwZTIiCgoJCQlpZiAoZnN0eXBlICYmIHN0cmNtcChtdGN1ci0+bW50X3R5cGUsIGZzdHlwZSkpIGNvbnRpbnVlOwoKCQkJLy8gU2tpcCBub2F1dG8gYW5kIHN3YXAgYW55d2F5LgoKCQkJaWYgKHBhcnNlX21vdW50X29wdGlvbnMobXRjdXItPm1udF9vcHRzLCAwKQoJCQkJJiAoTU9VTlRfTk9BVVRPIHwgTU9VTlRfU1dBUCkpIGNvbnRpbnVlOwoKCQkJLy8gTm8sIG1vdW50IC1hIHdvbid0IG1vdW50IGFueXRoaW5nLAoJCQkvLyBldmVuIHVzZXIgbW91bnRzLCBmb3IgbWVyZSBodW1hbnMuCgoJCQlpZiAobm9ucm9vdCkKCQkJCWJiX2Vycm9yX21zZ19hbmRfZGllKG11c3RfYmVfcm9vdCk7CgoJCQkvLyBNb3VudCB0aGlzIHRoaW5nLgoKCQkJLy8gTkZTIG1vdW50cyB3YW50IHRoaXMgdG8gYmUgeHJlYWxsb2MtYWJsZQoJCQltdGN1ci0+bW50X29wdHMgPSB4c3RyZHVwKG10Y3VyLT5tbnRfb3B0cyk7CgkJCWlmIChzaW5nbGVtb3VudChtdGN1ciwgMSkpIHsKCQkJCS8qIENvdW50IG51bWJlciBvZiBmYWlsZWQgbW91bnRzICovCgkJCQlyYysrOwoJCQl9CgkJCWZyZWUobXRjdXItPm1udF9vcHRzKTsKCQl9Cgl9CglpZiAoRU5BQkxFX0ZFQVRVUkVfQ0xFQU5fVVApIGVuZG1udGVudChmc3RhYik7CgpjbGVhbl91cDoKCglpZiAoRU5BQkxFX0ZFQVRVUkVfQ0xFQU5fVVApIHsKCQlmcmVlKHN0b3JhZ2VfcGF0aCk7CgkJZnJlZShjbWRvcHRzKTsKCX0KCglyZXR1cm4gcmM7Cn0K