LyoKICogRGVidWdnZXIgc3RhY2sgaGFuZGxpbmcKICoKICogQ29weXJpZ2h0IDE5OTUgQWxleGFuZHJlIEp1bGxpYXJkCiAqIENvcHlyaWdodCAxOTk2IEVyaWMgWW91bmdkYWxlCiAqIENvcHlyaWdodCAxOTk5IE92ZSBL5XZlbgogKi8KCiNpbmNsdWRlICJjb25maWcuaCIKCiNpbmNsdWRlIDxzdGRsaWIuaD4KCiNpbmNsdWRlICJkZWJ1Z2dlci5oIgojaW5jbHVkZSAic3RhY2tmcmFtZS5oIgojaW5jbHVkZSAid2luYmFzZS5oIgoKI2lmZGVmIF9faTM4Nl9fCi8qCiAqIFdlIGtlZXAgdGhpcyBpbmZvIGZvciBlYWNoIGZyYW1lLCBzbyB0aGF0IHdlIGNhbgogKiBmaW5kIGxvY2FsIHZhcmlhYmxlIGluZm9ybWF0aW9uIGNvcnJlY3RseS4KICovCnN0cnVjdCBidF9pbmZvCnsKICB1bnNpZ25lZCBpbnQJICAgICBjczsKICB1bnNpZ25lZCBpbnQJICAgICBlaXA7CiAgdW5zaWduZWQgaW50CSAgICAgc3M7CiAgdW5zaWduZWQgaW50CSAgICAgZWJwOwogIHN0cnVjdCBzeW1ib2xfaW5mbyBmcmFtZTsKfTsKCnN0YXRpYyBpbnQgbmZyYW1lOwpzdGF0aWMgc3RydWN0IGJ0X2luZm8gKiBmcmFtZXMgPSBOVUxMOwppbnQgY3Vycl9mcmFtZTsKCnR5cGVkZWYgc3RydWN0CnsKICAgIFdPUkQgYnA7CiAgICBXT1JEIGlwOwogICAgV09SRCBjczsKfSBGUkFNRTE2OwoKdHlwZWRlZiBzdHJ1Y3QKewogICAgRFdPUkQgYnA7CiAgICBEV09SRCBpcDsKICAgIFdPUkQgY3M7Cn0gRlJBTUUzMjsKI2VuZGlmCgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICBERUJVR19JbmZvU3RhY2sKICoKICogRHVtcCB0aGUgdG9wIG9mIHRoZSBzdGFjawogKi8Kdm9pZCBERUJVR19JbmZvU3RhY2sodm9pZCkKewojaWZkZWYgX19pMzg2X18KICAgIERCR19WQUxVRQl2YWx1ZTsKICAgIAogICAgdmFsdWUudHlwZSA9IE5VTEw7CiAgICB2YWx1ZS5jb29raWUgPSBEVl9UQVJHRVQ7CiAgICB2YWx1ZS5hZGRyLnNlZyA9IERFQlVHX2NvbnRleHQuU2VnU3M7CiAgICB2YWx1ZS5hZGRyLm9mZiA9IERFQlVHX2NvbnRleHQuRXNwOwoKICAgIERFQlVHX1ByaW50ZihEQkdfQ0hOX01FU0csIlN0YWNrIGR1bXA6XG4iKTsKICAgIHN3aXRjaCAoREVCVUdfR2V0U2VsZWN0b3JUeXBlKHZhbHVlLmFkZHIuc2VnKSkgewogICAgY2FzZSAzMjogLyogMzItYml0IG1vZGUgKi8KICAgICAgIERFQlVHX0V4YW1pbmVNZW1vcnkoICZ2YWx1ZSwgMjQsICd4JyApOwogICAgICAgYnJlYWs7CiAgICBjYXNlIDE2OiAgLyogMTYtYml0IG1vZGUgKi8KICAgICAgICB2YWx1ZS5hZGRyLm9mZiAmPSAweGZmZmY7CiAgICAgICAgREVCVUdfRXhhbWluZU1lbW9yeSggJnZhbHVlLCAyNCwgJ3cnICk7CglicmVhazsKICAgIGRlZmF1bHQ6CiAgICAgICBERUJVR19QcmludGYoREJHX0NITl9NRVNHLCAiQmFkIHNlZ21lbnQgKCVsZClcbiIsIHZhbHVlLmFkZHIuc2VnKTsKICAgIH0KICAgIERFQlVHX1ByaW50ZihEQkdfQ0hOX01FU0csIlxuIik7CiNlbmRpZgp9CgojaWZkZWYgX19pMzg2X18Kc3RhdGljIHZvaWQgREVCVUdfRm9yY2VGcmFtZShEQkdfQUREUiAqc3RhY2ssIERCR19BRERSICpjb2RlLCBpbnQgZnJhbWVubywgaW50IGJpdHMsIGludCBub2lzeSkKewogICAgaW50IHRoZWZyYW1lID0gbmZyYW1lKys7CiAgICBmcmFtZXMgPSAoc3RydWN0IGJ0X2luZm8gKilEQkdfcmVhbGxvYyhmcmFtZXMsCgkJCQkJICAgbmZyYW1lKnNpemVvZihzdHJ1Y3QgYnRfaW5mbykpOwogICAgaWYgKG5vaXN5KQogICAgICBERUJVR19QcmludGYoREJHX0NITl9NRVNHLCIlcyVkICIsICh0aGVmcmFtZSA9PSBjdXJyX2ZyYW1lID8gIj0+IiA6ICIgICIpLAogICAgICAgICAgICAgIGZyYW1lbm8pOwogICAgZnJhbWVzW3RoZWZyYW1lXS5jcyA9IGNvZGUtPnNlZzsKICAgIGZyYW1lc1t0aGVmcmFtZV0uZWlwID0gY29kZS0+b2ZmOwogICAgaWYgKG5vaXN5KQogICAgICBmcmFtZXNbdGhlZnJhbWVdLmZyYW1lID0gREVCVUdfUHJpbnRBZGRyZXNzQW5kQXJncyggY29kZSwgYml0cywgCgkJCQkJCQkgIHN0YWNrLT5vZmYsIFRSVUUgKTsKICAgIGVsc2UKICAgICAgREVCVUdfRmluZE5lYXJlc3RTeW1ib2woIGNvZGUsIFRSVUUsIAoJCQkgICAgICAgJmZyYW1lc1t0aGVmcmFtZV0uZnJhbWUuc3ltLCBzdGFjay0+b2ZmLCAKCQkJICAgICAgICZmcmFtZXNbdGhlZnJhbWVdLmZyYW1lLmxpc3QpOwogICAgZnJhbWVzW3RoZWZyYW1lXS5zcyA9IHN0YWNrLT5zZWc7CiAgICBmcmFtZXNbdGhlZnJhbWVdLmVicCA9IHN0YWNrLT5vZmY7CiAgICBpZiAobm9pc3kpIHsKICAgICAgREVCVUdfUHJpbnRmKCBEQkdfQ0hOX01FU0csIChiaXRzID09IDE2KSA/ICIgKGJwPSUwNGx4KVxuIiA6ICIgKGVicD0lMDhseClcbiIsIHN0YWNrLT5vZmYgKTsKICAgIH0KfQoKc3RhdGljIEJPT0wgREVCVUdfRnJhbWUxNihEQkdfQUREUiAqYWRkciwgdW5zaWduZWQgaW50ICpjcywgaW50IGZyYW1lbm8sIGludCBub2lzeSkKewogICAgdW5zaWduZWQgaW50CXNzID0gYWRkci0+c2VnLCBwb3NzaWJsZV9jcyA9IDA7CiAgICBGUkFNRTE2IAkJZnJhbWU7CiAgICBpbnQgCQl0aGVmcmFtZSA9IG5mcmFtZTsKICAgIHZvaWQqCQlwID0gKHZvaWQqKURFQlVHX1RvTGluZWFyKGFkZHIpOwogICAgCiAgICBpZiAoIXApIHJldHVybiBGQUxTRTsKICAgIAogICAgaWYgKCFERUJVR19SRUFEX01FTShwLCAmZnJhbWUsIHNpemVvZihmcmFtZSkpKSB7CiAgICAgICAgaWYgKG5vaXN5KSBERUJVR19JbnZhbEFkZHIoYWRkcik7CglyZXR1cm4gRkFMU0U7CiAgICB9CiAgICBpZiAoIWZyYW1lLmJwKSByZXR1cm4gRkFMU0U7CiAgICBuZnJhbWUrKzsKICAgIGZyYW1lcyA9IChzdHJ1Y3QgYnRfaW5mbyAqKURCR19yZWFsbG9jKGZyYW1lcywKCQkJCQkgICBuZnJhbWUqc2l6ZW9mKHN0cnVjdCBidF9pbmZvKSk7CiAgICBpZiAobm9pc3kpCiAgICAgICAgREVCVUdfUHJpbnRmKERCR19DSE5fTUVTRywiJXMlZCAiLCAodGhlZnJhbWUgPT0gY3Vycl9mcmFtZSA/ICI9PiIgOiAiICAiKSwKCQkgICAgIGZyYW1lbm8pOwogICAgaWYgKGZyYW1lLmJwICYgMSkgKmNzID0gZnJhbWUuY3M7CiAgICBlbHNlIHsKICAgICAgICAvKiBub3QgZXhwbGljaXRseSBtYXJrZWQgYXMgZmFyIGNhbGwsCgkgKiBidXQgY2hlY2sgd2hldGhlciBpdCBjb3VsZCBiZSBhbnl3YXkgKi8KICAgICAgICBpZiAoKChmcmFtZS5jcyY3KT09NykgJiYgKGZyYW1lLmNzICE9ICpjcykpIHsKCSAgICBMRFRfRU5UUlkJbGU7CgkgCgkgICAgaWYgKEdldFRocmVhZFNlbGVjdG9yRW50cnkoIERFQlVHX0N1cnJUaHJlYWQtPmhhbmRsZSwgZnJhbWUuY3MsICZsZSkgJiYKCQkobGUuSGlnaFdvcmQuQml0cy5UeXBlICYgMHgwOCkpIHsgLyogY29kZSBzZWdtZW50ICovCgkgICAgICAgIC8qIGl0IGlzIHZlcnkgdW5jb21tb24gdG8gcHVzaCBhIGNvZGUgc2VnbWVudCBjcyBhcwoJCSAqIGEgcGFyYW1ldGVyLCBzbyB0aGlzIHNob3VsZCB3b3JrIGluIG1vc3QgY2FzZXMgKi8KCSAgICAgICAgKmNzID0gcG9zc2libGVfY3MgPSBmcmFtZS5jczsKCSAgICB9Cgl9CiAgICB9CiAgICBmcmFtZXNbdGhlZnJhbWVdLmNzID0gYWRkci0+c2VnID0gKmNzOwogICAgZnJhbWVzW3RoZWZyYW1lXS5laXAgPSBhZGRyLT5vZmYgPSBmcmFtZS5pcDsKICAgIGlmIChub2lzeSkKICAgICAgICBmcmFtZXNbdGhlZnJhbWVdLmZyYW1lID0gREVCVUdfUHJpbnRBZGRyZXNzQW5kQXJncyggYWRkciwgMTYsIAoJCQkJCQkJICAgIGZyYW1lLmJwLCBUUlVFICk7CiAgICBlbHNlCiAgICAgICAgREVCVUdfRmluZE5lYXJlc3RTeW1ib2woIGFkZHIsIFRSVUUsIAoJCQkJICZmcmFtZXNbdGhlZnJhbWVdLmZyYW1lLnN5bSwgZnJhbWUuYnAsIAoJCQkJICZmcmFtZXNbdGhlZnJhbWVdLmZyYW1lLmxpc3QpOwogICAgZnJhbWVzW3RoZWZyYW1lXS5zcyA9IGFkZHItPnNlZyA9IHNzOwogICAgZnJhbWVzW3RoZWZyYW1lXS5lYnAgPSBhZGRyLT5vZmYgPSBmcmFtZS5icCAmIH4xOwogICAgaWYgKG5vaXN5KSB7CiAgICAgICAgREVCVUdfUHJpbnRmKCBEQkdfQ0hOX01FU0csICIgKGJwPSUwNGx4IiwgYWRkci0+b2ZmICk7CiAgICAgICAgaWYgKHBvc3NpYmxlX2NzKSB7CgkgICAgREVCVUdfUHJpbnRmKCBEQkdfQ0hOX01FU0csICIsIGZhciBjYWxsIGFzc3VtZWQiICk7Cgl9CglERUJVR19QcmludGYoIERCR19DSE5fTUVTRywgIilcbiIgKTsKICAgIH0KICAgIHJldHVybiBUUlVFOwp9CgpzdGF0aWMgQk9PTCBERUJVR19GcmFtZTMyKERCR19BRERSICphZGRyLCB1bnNpZ25lZCBpbnQgKmNzLCBpbnQgZnJhbWVubywgaW50IG5vaXN5KQp7CiAgICB1bnNpZ25lZCBpbnQgCXNzID0gYWRkci0+c2VnOwogICAgRlJBTUUzMiAJCWZyYW1lOwogICAgaW50IAkJdGhlZnJhbWUgPSBuZnJhbWU7CiAgICB2b2lkKgkJcCA9ICh2b2lkKilERUJVR19Ub0xpbmVhcihhZGRyKTsKICAgIAogICAgaWYgKCFwKSByZXR1cm4gRkFMU0U7CiAgICAKICAgIGlmICghREVCVUdfUkVBRF9NRU0ocCwgJmZyYW1lLCBzaXplb2YoZnJhbWUpKSkgewogICAgICAgaWYgKG5vaXN5KSBERUJVR19JbnZhbEFkZHIoYWRkcik7CiAgICAgICByZXR1cm4gRkFMU0U7CiAgICB9CiAgICBpZiAoIWZyYW1lLmlwKSByZXR1cm4gRkFMU0U7CiAgICAKICAgIG5mcmFtZSsrOwogICAgZnJhbWVzID0gKHN0cnVjdCBidF9pbmZvICopREJHX3JlYWxsb2MoZnJhbWVzLAoJCQkJCSAgIG5mcmFtZSpzaXplb2Yoc3RydWN0IGJ0X2luZm8pKTsKICAgIGlmIChub2lzeSkKICAgICAgIERFQlVHX1ByaW50ZihEQkdfQ0hOX01FU0csIiVzJWQgIiwgKHRoZWZyYW1lID09IGN1cnJfZnJhbWUgPyAiPT4iIDogIiAgIiksCgkJICAgIGZyYW1lbm8pOwogICAgZnJhbWVzW3RoZWZyYW1lXS5jcyA9IGFkZHItPnNlZyA9ICpjczsKICAgIGZyYW1lc1t0aGVmcmFtZV0uZWlwID0gYWRkci0+b2ZmID0gZnJhbWUuaXA7CiAgICBpZiAobm9pc3kpCiAgICAgICAgZnJhbWVzW3RoZWZyYW1lXS5mcmFtZSA9IERFQlVHX1ByaW50QWRkcmVzc0FuZEFyZ3MoIGFkZHIsIDMyLCAKCQkJCQkJCSAgICBmcmFtZS5icCwgVFJVRSApOwogICAgZWxzZQogICAgICAgIERFQlVHX0ZpbmROZWFyZXN0U3ltYm9sKCBhZGRyLCBUUlVFLCAKCQkJCSAmZnJhbWVzW3RoZWZyYW1lXS5mcmFtZS5zeW0sIGZyYW1lLmJwLCAKCQkJCSAmZnJhbWVzW3RoZWZyYW1lXS5mcmFtZS5saXN0KTsKICAgIGlmIChub2lzeSkgREVCVUdfUHJpbnRmKCBEQkdfQ0hOX01FU0csICIgKGVicD0lMDhseClcbiIsIGZyYW1lLmJwICk7CiAgICBmcmFtZXNbdGhlZnJhbWVdLnNzID0gYWRkci0+c2VnID0gc3M7CiAgICBmcmFtZXNbdGhlZnJhbWVdLmVicCA9IGZyYW1lLmJwOwogICAgaWYgKGFkZHItPm9mZiA9PSBmcmFtZS5icCkgcmV0dXJuIEZBTFNFOwogICAgYWRkci0+b2ZmID0gZnJhbWUuYnA7CiAgICByZXR1cm4gVFJVRTsKfQojZW5kaWYKCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgIERFQlVHX0JhY2tUcmFjZQogKgogKiBEaXNwbGF5IGEgc3RhY2sgYmFjay10cmFjZS4KICovCnZvaWQgREVCVUdfQmFja1RyYWNlKEJPT0wgbm9pc3kpCnsKI2lmZGVmIF9faTM4NgogICAgREJHX0FERFIgCQlhZGRyLCBzd19hZGRyLCBjb2RlLCB0bXA7CiAgICB1bnNpZ25lZCBpbnQgCXNzID0gREVCVUdfY29udGV4dC5TZWdTczsKICAgIHVuc2lnbmVkIGludAljcyA9IERFQlVHX2NvbnRleHQuU2VnQ3M7CiAgICBpbnQgCQlmcmFtZW5vID0gMCwgaXMxNiwgb2s7CiAgICBEV09SRCAJCW5leHRfc3dpdGNoLCBjdXJfc3dpdGNoLCBwOwogICAgU1RBQ0sxNkZSQU1FICAgICAgIAlmcmFtZTE2OwogICAgU1RBQ0szMkZSQU1FICAgICAgIAlmcmFtZTMyOwogICAgY2hhcgkJY2g7CgogICAgaWYgKG5vaXN5KSBERUJVR19QcmludGYoIERCR19DSE5fTUVTRywgIkJhY2t0cmFjZTpcbiIgKTsKCiAgICBuZnJhbWUgPSAxOwogICAgaWYgKGZyYW1lcykgREJHX2ZyZWUoIGZyYW1lcyApOwogICAgZnJhbWVzID0gKHN0cnVjdCBidF9pbmZvICopIERCR19hbGxvYyggc2l6ZW9mKHN0cnVjdCBidF9pbmZvKSApOwogICAgaWYgKG5vaXN5KQogICAgICAgIERFQlVHX1ByaW50ZihEQkdfQ0hOX01FU0csIiVzJWQgIiwoY3Vycl9mcmFtZSA9PSAwID8gIj0+IiA6ICIgICIpLCBmcmFtZW5vKTsKCiAgICBpZiAoREVCVUdfSXNTZWxlY3RvclN5c3RlbShzcykpIHNzID0gMDsKICAgIGlmIChERUJVR19Jc1NlbGVjdG9yU3lzdGVtKGNzKSkgY3MgPSAwOwoKICAgIC8qIGZpcnN0IHN0YWNrIGZyYW1lIGZyb20gcmVnaXN0ZXJzICovCiAgICBzd2l0Y2ggKERFQlVHX0dldFNlbGVjdG9yVHlwZShzcykpCiAgICB7CiAgICBjYXNlIDMyOgogICAgICAgIGZyYW1lc1swXS5jcyA9IGFkZHIuc2VnID0gY3M7CiAgICAgICAgZnJhbWVzWzBdLmVpcCA9IGFkZHIub2ZmID0gREVCVUdfY29udGV4dC5FaXA7CiAgICAgICAgaWYgKG5vaXN5KQogICAgICAgICAgICBmcmFtZXNbMF0uZnJhbWUgPSBERUJVR19QcmludEFkZHJlc3MoICZhZGRyLCAzMiwgVFJVRSApOwogICAgICAgIGVsc2UKCSAgICBERUJVR19GaW5kTmVhcmVzdFN5bWJvbCggJmFkZHIsIFRSVUUsICZmcmFtZXNbMF0uZnJhbWUuc3ltLCAwLCAKCQkJCSAgICAgJmZyYW1lc1swXS5mcmFtZS5saXN0KTsKICAgICAgICBmcmFtZXNbMF0uc3MgPSBhZGRyLnNlZyA9IHNzOwoJZnJhbWVzWzBdLmVicCA9IGFkZHIub2ZmID0gREVCVUdfY29udGV4dC5FYnA7CiAgICAgICAgaWYgKG5vaXN5KSBERUJVR19QcmludGYoIERCR19DSE5fTUVTRywgIiAoZWJwPSUwOHgpXG4iLCBmcmFtZXNbMF0uZWJwICk7CiAgICAgICAgaXMxNiA9IEZBTFNFOwoJYnJlYWs7CiAgICBjYXNlIDE2OgogICAgICAgIGZyYW1lc1swXS5jcyA9IGFkZHIuc2VnID0gY3M7CiAgICAgICAgZnJhbWVzWzBdLmVpcCA9IGFkZHIub2ZmID0gTE9XT1JEKERFQlVHX2NvbnRleHQuRWlwKTsKICAgICAgICBpZiAobm9pc3kpCgkgICAgZnJhbWVzWzBdLmZyYW1lID0gREVCVUdfUHJpbnRBZGRyZXNzKCAmYWRkciwgMTYsIFRSVUUgKTsKICAgICAgICBlbHNlCgkgICAgREVCVUdfRmluZE5lYXJlc3RTeW1ib2woICZhZGRyLCBUUlVFLCAmZnJhbWVzWzBdLmZyYW1lLnN5bSwgMCwgCgkJCQkgICAgICZmcmFtZXNbMF0uZnJhbWUubGlzdCk7CiAgICAgICAgZnJhbWVzWzBdLnNzID0gYWRkci5zZWcgPSBzczsKCWZyYW1lc1swXS5lYnAgPSBhZGRyLm9mZiA9IExPV09SRChERUJVR19jb250ZXh0LkVicCk7CiAgICAgICAgaWYgKG5vaXN5KSBERUJVR19QcmludGYoIERCR19DSE5fTUVTRywgIiAoYnA9JTA0eClcbiIsIGZyYW1lc1swXS5lYnAgKTsKICAgICAgICBpczE2ID0gVFJVRTsKCWJyZWFrOwogICAgZGVmYXVsdDoKICAgICAgICBpZiAobm9pc3kpIERFQlVHX1ByaW50ZiggREJHX0NITl9NRVNHLCAiQmFkIHNlZ21lbnQgJyV1J1xuIiwgc3MpOwoJcmV0dXJuOwogICAgfQoKICAgIC8qIGN1cl9zd2l0Y2ggaG9sZHMgYWRkcmVzcyBvZiBjdXJyX3N0YWNrJ3MgZmllbGQgaW4gVEVCIGluIGRlYnVnZ2VlIAogICAgICogYWRkcmVzcyBzcGFjZSAKICAgICAqLwogICAgY3VyX3N3aXRjaCA9IChEV09SRClERUJVR19DdXJyVGhyZWFkLT50ZWIgKyBPRkZTRVRfT0YoVEVCLCBjdXJfc3RhY2spOwogICAgaWYgKCFERUJVR19SRUFEX01FTSgodm9pZCopY3VyX3N3aXRjaCwgJm5leHRfc3dpdGNoLCBzaXplb2YobmV4dF9zd2l0Y2gpKSkgewogICAgICAgIGlmIChub2lzeSkgREVCVUdfUHJpbnRmKCBEQkdfQ0hOX01FU0csICJDYW4ndCByZWFkIFRFQjpjdXJfc3RhY2tcbiIpOwoJcmV0dXJuOwogICAgfQoKICAgIGlmIChpczE2KSB7CiAgICAgICAgaWYgKCFERUJVR19SRUFEX01FTSgodm9pZCopbmV4dF9zd2l0Y2gsICZmcmFtZTMyLCBzaXplb2YoU1RBQ0szMkZSQU1FKSkpIHsKCSAgICBpZiAobm9pc3kpIERFQlVHX1ByaW50ZiggREJHX0NITl9NRVNHLCAiQmFkIHN0YWNrIGZyYW1lICVwXG4iLCAKCQkJCSAgICAgKFNUQUNLMzJGUkFNRSopbmV4dF9zd2l0Y2ggKTsKCSAgICByZXR1cm47Cgl9CgljdXJfc3dpdGNoID0gKERXT1JEKWZyYW1lMzIuZnJhbWUxNjsKCXN3X2FkZHIuc2VnID0gU0VMRUNUT1JPRihjdXJfc3dpdGNoKTsKCXN3X2FkZHIub2ZmID0gT0ZGU0VUT0YoY3VyX3N3aXRjaCk7CiAgICB9IGVsc2UgewogICAgICAgIHRtcC5zZWcgPSBTRUxFQ1RPUk9GKG5leHRfc3dpdGNoKTsKCXRtcC5vZmYgPSBPRkZTRVRPRihuZXh0X3N3aXRjaCk7CglwID0gREVCVUdfVG9MaW5lYXIoJnRtcCk7CgkKCWlmICghREVCVUdfUkVBRF9NRU0oKHZvaWQqKXAsICZmcmFtZTE2LCBzaXplb2YoU1RBQ0sxNkZSQU1FKSkpIHsKCSAgICBpZiAobm9pc3kpIERFQlVHX1ByaW50ZiggREJHX0NITl9NRVNHLCAiQmFkIHN0YWNrIGZyYW1lICVwXG4iLCAoU1RBQ0sxNkZSQU1FKilwICk7CgkgICAgcmV0dXJuOwoJfQoJY3VyX3N3aXRjaCA9IChEV09SRClmcmFtZTE2LmZyYW1lMzI7Cglzd19hZGRyLnNlZyA9IHNzOwoJc3dfYWRkci5vZmYgPSBjdXJfc3dpdGNoOwogICAgfQogICAgaWYgKCFERUJVR19SRUFEX01FTSgodm9pZCopREVCVUdfVG9MaW5lYXIoJnN3X2FkZHIpLCAmY2gsIHNpemVvZihjaCkpKSB7CiAgICAgICAgc3dfYWRkci5zZWcgPSAoRFdPUkQpLTE7Cglzd19hZGRyLm9mZiA9IChEV09SRCktMTsKICAgIH0KICAgIAogICAgZm9yIChvayA9IFRSVUU7IG9rOykgewogICAgICAgIGlmICgoZnJhbWVzW2ZyYW1lbm9dLnNzID09IHN3X2FkZHIuc2VnKSAmJgoJICAgIChmcmFtZXNbZnJhbWVub10uZWJwID49IHN3X2FkZHIub2ZmKSkgewoJICAgLyogMTY8LT4zMiBzd2l0Y2guLi4KCSAgICAqIHllcywgSSBrbm93IHRoaXMgaXMgY29uZnVzaW5nLCBpdCBnYXZlIG1lIGEgaGVhZGFjaGUgdG9vICovCgkgICBpZiAoaXMxNikgewoJICAgICAgCgkgICAgICAgaWYgKCFERUJVR19SRUFEX01FTSgodm9pZCopbmV4dF9zd2l0Y2gsICZmcmFtZTMyLCBzaXplb2YoU1RBQ0szMkZSQU1FKSkpIHsKCQkgIGlmIChub2lzeSkgREVCVUdfUHJpbnRmKCBEQkdfQ0hOX01FU0csICJCYWQgc3RhY2sgZnJhbWUgJXBcbiIsIChTVEFDSzMyRlJBTUUqKW5leHRfc3dpdGNoICk7CgkJICByZXR1cm47CgkgICAgICAgfQoKCSAgICAgICBjb2RlLnNlZyAgPSAwOwoJICAgICAgIGNvZGUub2ZmICA9IGZyYW1lMzIucmV0YWRkcjsKCSAgICAgICAKCSAgICAgICBjcyA9IDA7CgkgICAgICAgYWRkci5zZWcgPSAwOwoJICAgICAgIGFkZHIub2ZmID0gZnJhbWUzMi5lYnA7CgkgICAgICAgREVCVUdfRm9yY2VGcmFtZSggJmFkZHIsICZjb2RlLCArK2ZyYW1lbm8sIDMyLCBub2lzeSApOwoJICAgICAgIAoJICAgICAgIG5leHRfc3dpdGNoID0gY3VyX3N3aXRjaDsKCSAgICAgICB0bXAuc2VnID0gU0VMRUNUT1JPRihuZXh0X3N3aXRjaCk7CgkgICAgICAgdG1wLm9mZiA9IE9GRlNFVE9GKG5leHRfc3dpdGNoKTsKCSAgICAgICBwID0gREVCVUdfVG9MaW5lYXIoJnRtcCk7CgkgICAgICAgCgkgICAgICAgaWYgKCFERUJVR19SRUFEX01FTSgodm9pZCopcCwgJmZyYW1lMTYsIHNpemVvZihTVEFDSzE2RlJBTUUpKSkgewoJCSAgIGlmIChub2lzeSkgREVCVUdfUHJpbnRmKCBEQkdfQ0hOX01FU0csICJCYWQgc3RhY2sgZnJhbWUgJXBcbiIsIAoJCQkJCSAgICAoU1RBQ0sxNkZSQU1FKilwICk7CgkJICAgcmV0dXJuOwoJICAgICAgIH0KCSAgICAgICBjdXJfc3dpdGNoID0gKERXT1JEKWZyYW1lMTYuZnJhbWUzMjsKCSAgICAgICBzd19hZGRyLnNlZyA9IDA7CgkgICAgICAgc3dfYWRkci5vZmYgPSBjdXJfc3dpdGNoOwoJICAgICAgIAoJICAgICAgIGlzMTYgPSBGQUxTRTsKCSAgIH0gZWxzZSB7CgkgICAgICB0bXAuc2VnID0gU0VMRUNUT1JPRihuZXh0X3N3aXRjaCk7CgkgICAgICB0bXAub2ZmID0gT0ZGU0VUT0YobmV4dF9zd2l0Y2gpOwoJICAgICAgcCA9IERFQlVHX1RvTGluZWFyKCZ0bXApOwoJICAgICAgCgkgICAgICBpZiAoIURFQlVHX1JFQURfTUVNKCh2b2lkKilwLCAmZnJhbWUxNiwgc2l6ZW9mKFNUQUNLMTZGUkFNRSkpKSB7CgkJICBpZiAobm9pc3kpIERFQlVHX1ByaW50ZiggREJHX0NITl9NRVNHLCAiQmFkIHN0YWNrIGZyYW1lICVwXG4iLAoJCQkJCSAgIChTVEFDSzE2RlJBTUUqKXAgKTsKCQkgIHJldHVybjsKCSAgICAgIH0KCSAgICAgIAoJICAgICAgY29kZS5zZWcgID0gZnJhbWUxNi5jczsKCSAgICAgIGNvZGUub2ZmICA9IGZyYW1lMTYuaXA7CgkgICAgICAKCSAgICAgIGNzID0gZnJhbWUxNi5jczsKCSAgICAgIGFkZHIuc2VnID0gU0VMRUNUT1JPRihuZXh0X3N3aXRjaCk7CgkgICAgICBhZGRyLm9mZiA9IGZyYW1lMTYuYnA7CgkgICAgICBERUJVR19Gb3JjZUZyYW1lKCAmYWRkciwgJmNvZGUsICsrZnJhbWVubywgMTYsIG5vaXN5ICk7CgkgICAgICAKCSAgICAgIG5leHRfc3dpdGNoID0gY3VyX3N3aXRjaDsKCSAgICAgIGlmICghREVCVUdfUkVBRF9NRU0oKHZvaWQqKW5leHRfc3dpdGNoLCAmZnJhbWUzMiwgc2l6ZW9mKFNUQUNLMzJGUkFNRSkpKSB7CgkJIGlmIChub2lzeSkgREVCVUdfUHJpbnRmKCBEQkdfQ0hOX01FU0csICJCYWQgc3RhY2sgZnJhbWUgJXBcbiIsIAoJCQkJCSAgKFNUQUNLMzJGUkFNRSopbmV4dF9zd2l0Y2ggKTsKCQkgcmV0dXJuOwoJICAgICAgfQoJICAgICAgY3VyX3N3aXRjaCA9IChEV09SRClmcmFtZTMyLmZyYW1lMTY7CgkgICAgICBzd19hZGRyLnNlZyA9IFNFTEVDVE9ST0YoY3VyX3N3aXRjaCk7CgkgICAgICBzd19hZGRyLm9mZiA9IE9GRlNFVE9GKGN1cl9zd2l0Y2gpOwoJICAgICAgCgkgICAgICBpczE2ID0gVFJVRTsKCSAgIH0KCSAgIGlmICghREVCVUdfUkVBRF9NRU0oKHZvaWQqKURFQlVHX1RvTGluZWFyKCZzd19hZGRyKSwgJmNoLCBzaXplb2YoY2gpKSkgewoJICAgICAgc3dfYWRkci5zZWcgPSAoRFdPUkQpLTE7CgkgICAgICBzd19hZGRyLm9mZiA9IChEV09SRCktMTsKCSAgIH0KCX0gZWxzZSB7CgkgICAgLyogb3JkaW5hcnkgc3RhY2sgZnJhbWUgKi8KCSAgIG9rID0gaXMxNiA/IERFQlVHX0ZyYW1lMTYoICZhZGRyLCAmY3MsICsrZnJhbWVubywgbm9pc3kpCgkgICAgICA6IERFQlVHX0ZyYW1lMzIoICZhZGRyLCAmY3MsICsrZnJhbWVubywgbm9pc3kpOwoJfQogICAgfQogICAgaWYgKG5vaXN5KSBERUJVR19QcmludGYoIERCR19DSE5fTUVTRywgIlxuIiApOwojZW5kaWYKfQoKaW50CkRFQlVHX1NldEZyYW1lKGludCBuZXdmcmFtZSkKewogIGludAkJcnRuID0gRkFMU0U7CgogIGN1cnJfZnJhbWUgPSBuZXdmcmFtZTsKCiAgaWYoIGN1cnJfZnJhbWUgPj0gbmZyYW1lICkKICAgIHsKICAgICAgY3Vycl9mcmFtZSA9IG5mcmFtZSAtIDE7CiAgICB9CgogIGlmKCBjdXJyX2ZyYW1lIDwgMCApCiAgICB7CiAgICAgIGN1cnJfZnJhbWUgPSAwOwogICAgfQoKICAgaWYoIGZyYW1lcyAmJiBmcmFtZXNbY3Vycl9mcmFtZV0uZnJhbWUubGlzdC5zb3VyY2VmaWxlICE9IE5VTEwgKQogICAgewogICAgICBERUJVR19MaXN0KCZmcmFtZXNbY3Vycl9mcmFtZV0uZnJhbWUubGlzdCwgTlVMTCwgMCk7CiAgICB9CgogIHJ0biA9IFRSVUU7CiAgcmV0dXJuIChydG4pOwp9CgppbnQKREVCVUdfR2V0Q3VycmVudEZyYW1lKHN0cnVjdCBuYW1lX2hhc2ggKiogbmFtZSwgdW5zaWduZWQgaW50ICogZWlwLAoJCSAgICAgIHVuc2lnbmVkIGludCAqIGVicCkKewogIC8qCiAgICogSWYgd2UgZG9uJ3QgaGF2ZSBhIHZhbGlkIGJhY2t0cmFjZSwgdGhlbiBqdXN0IHJldHVybi4KICAgKi8KICBpZiggZnJhbWVzID09IE5VTEwgKQogICAgewogICAgICByZXR1cm4gRkFMU0U7CiAgICB9CgogIC8qCiAgICogSWYgd2UgZG9uJ3Qga25vdyB3aGF0IHRoZSBjdXJyZW50IGZ1bmN0aW9uIGlzLCB0aGVuIHdlIGFsc28gaGF2ZQogICAqIG5vdGhpbmcgdG8gcmVwb3J0IGhlcmUuCiAgICovCiAgaWYoIGZyYW1lc1tjdXJyX2ZyYW1lXS5mcmFtZS5zeW0gPT0gTlVMTCApCiAgICB7CiAgICAgIHJldHVybiBGQUxTRTsKICAgIH0KCiAgKm5hbWUgPSBmcmFtZXNbY3Vycl9mcmFtZV0uZnJhbWUuc3ltOwogICplaXAgPSBmcmFtZXNbY3Vycl9mcmFtZV0uZWlwOwogICplYnAgPSBmcmFtZXNbY3Vycl9mcmFtZV0uZWJwOwoKICByZXR1cm4gVFJVRTsKfQoK