LyoKICogZmF0LmMKICoKICogUi9PIChWKUZBVCAxMi8xNi8zMiBmaWxlc3lzdGVtIGltcGxlbWVudGF0aW9uIGJ5IE1hcmN1cyBTdW5kYmVyZwogKgogKiAyMDAyLTA3LTI4IC0gcmpvbmVzQG5leHVzLXRlY2gubmV0IC0gcG9ydGVkIHRvIHBwY2Jvb3QgdjEuMS42CiAqIDIwMDMtMDMtMTAgLSBraGFycmlzQG5leHVzLXRlY2gubmV0IC0gcG9ydGVkIHRvIHVib290CiAqCiAqIFNlZSBmaWxlIENSRURJVFMgZm9yIGxpc3Qgb2YgcGVvcGxlIHdobyBjb250cmlidXRlZCB0byB0aGlzCiAqIHByb2plY3QuCiAqCiAqIFRoaXMgcHJvZ3JhbSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IKICogbW9kaWZ5IGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgYXMKICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlciB2ZXJzaW9uIDIgb2YKICogdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uCiAqCiAqIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLAogKiBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZgogKiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlCiAqIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCiAqIGFsb25nIHdpdGggdGhpcyBwcm9ncmFtOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlCiAqIEZvdW5kYXRpb24sIEluYy4sIDU5IFRlbXBsZSBQbGFjZSwgU3VpdGUgMzMwLCBCb3N0b24sCiAqIE1BIDAyMTExLTEzMDcgVVNBCiAqLwoKI2luY2x1ZGUgPGNvbW1vbi5oPgojaW5jbHVkZSA8Y29uZmlnLmg+CiNpbmNsdWRlIDxwYXJ0Lmg+CiNpbmNsdWRlIDxmYXQuaD4KI2luY2x1ZGUgPGFzbS9ieXRlb3JkZXIuaD4KCiNpZmRlZiBDRkdfQ01EX0ZBVAoKLyoKICogQ29udmVydCBhIHN0cmluZyB0byBsb3dlcmNhc2UuCiAqLwpzdGF0aWMgdm9pZApkb3duY2FzZShjaGFyICpzdHIpCnsKCXdoaWxlICgqc3RyICE9ICdcMCcpIHsKCQlUT0xPV0VSKCpzdHIpOwoJCXN0cisrOwoJfQp9CgpzdGF0aWMgIGJsb2NrX2Rldl9kZXNjX3QgKmN1cl9kZXYgPSBOVUxMOwpzdGF0aWMgdW5zaWduZWQgbG9uZyBwYXJ0X29mZnNldCA9IDA7CnN0YXRpYyBpbnQgY3VyX3BhcnQgPSAxOwoKI2RlZmluZSBET1NfUEFSVF9UQkxfT0ZGU0VUCTB4MWJlCiNkZWZpbmUgRE9TX1BBUlRfTUFHSUNfT0ZGU0VUCTB4MWZlCiNkZWZpbmUgRE9TX0ZTX1RZUEVfT0ZGU0VUCTB4NTIKCmludCBzdHJuY21wKGNvbnN0IGNoYXIgKiBjcyxjb25zdCBjaGFyICogY3Qsc2l6ZV90IGNvdW50KQp7CiAgICAgICAgcmVnaXN0ZXIgc2lnbmVkIGNoYXIgX19yZXMgPSAwOwoKICAgICAgICB3aGlsZSAoY291bnQpIHsKICAgICAgICAgICAgICAgIGlmICgoX19yZXMgPSAqY3MgLSAqY3QrKykgIT0gMCB8fCAhKmNzKyspCiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgY291bnQtLTsKICAgICAgICB9CgogICAgICAgIHJldHVybiBfX3JlczsKfQoKY2hhciAqIHN0cmNweShjaGFyICogZGVzdCxjb25zdCBjaGFyICpzcmMpCnsKICAgICAgICBjaGFyICp0bXAgPSBkZXN0OwoKICAgICAgICB3aGlsZSAoKCpkZXN0KysgPSAqc3JjKyspICE9ICdcMCcpCiAgICAgICAgICAgICAgICAvKiBub3RoaW5nICovOwogICAgICAgIHJldHVybiB0bXA7Cn0KCmludCBzdHJjbXAoY29uc3QgY2hhciAqIGNzLGNvbnN0IGNoYXIgKiBjdCkKewogICAgICAgIHJlZ2lzdGVyIHNpZ25lZCBjaGFyIF9fcmVzOwoKICAgICAgICB3aGlsZSAoMSkgewogICAgICAgICAgICAgICAgaWYgKChfX3JlcyA9ICpjcyAtICpjdCsrKSAhPSAwIHx8ICEqY3MrKykKICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gX19yZXM7Cn0Kdm9pZCAqIG1lbWNweSh2b2lkICogZGVzdCxjb25zdCB2b2lkICpzcmMsc2l6ZV90IGNvdW50KQp7CiAgICAgICAgY2hhciAqdG1wID0gKGNoYXIgKikgZGVzdCwgKnMgPSAoY2hhciAqKSBzcmM7CgogICAgICAgIHdoaWxlIChjb3VudC0tKQogICAgICAgICAgICAgICAgKnRtcCsrID0gKnMrKzsKCiAgICAgICAgcmV0dXJuIGRlc3Q7Cn0KCgppbnQgZGlza19yZWFkIChfX3UzMiBzdGFydGJsb2NrLCBfX3UzMiBnZXRzaXplLCBfX3U4ICogYnVmcHRyKQp7CglzdGFydGJsb2NrICs9IHBhcnRfb2Zmc2V0OwoJaWYgKGN1cl9kZXYgPT0gTlVMTCkKCQlyZXR1cm4gLTE7CglpZiAoY3VyX2Rldi0+YmxvY2tfcmVhZCkgewoJCXJldHVybiBjdXJfZGV2LT5ibG9ja19yZWFkIChjdXJfZGV2LT5kZXYsIHN0YXJ0YmxvY2ssIGdldHNpemUsICh1bnNpZ25lZCBsb25nICopYnVmcHRyKTsKCX0KCXJldHVybiAtMTsKfQoKCmludApmYXRfcmVnaXN0ZXJfZGV2aWNlKGJsb2NrX2Rldl9kZXNjX3QgKmRldl9kZXNjLCBpbnQgcGFydF9ubykKewoJdW5zaWduZWQgY2hhciBidWZmZXJbU0VDVE9SX1NJWkVdOwoKCWlmICghZGV2X2Rlc2MtPmJsb2NrX3JlYWQpCgkJcmV0dXJuIC0xOwoJY3VyX2Rldj1kZXZfZGVzYzsKCS8qIGNoZWNrIGlmIHdlIGhhdmUgYSBNQlIgKG9uIGZsb3BwaWVzIHdlIGhhdmUgb25seSBhIFBCUikgKi8KCWlmIChkZXZfZGVzYy0+YmxvY2tfcmVhZCAoZGV2X2Rlc2MtPmRldiwgMCwgMSwgKHVsb25nICopIGJ1ZmZlcikgIT0gMSkgewoJCXByaW50ZiAoIioqIENhbid0IHJlYWQgZnJvbSBkZXZpY2UgJWQgKipcbiIsIGRldl9kZXNjLT5kZXYpOwoJCXJldHVybiAtMTsKCX0KCWlmIChidWZmZXJbRE9TX1BBUlRfTUFHSUNfT0ZGU0VUXSAhPSAweDU1IHx8CgkJYnVmZmVyW0RPU19QQVJUX01BR0lDX09GRlNFVCArIDFdICE9IDB4YWEpIHsKCQkvKiBubyBzaWduYXR1cmUgZm91bmQgKi8KCQlyZXR1cm4gLTE7Cgl9CglpZighc3RybmNtcCgoY2hhciAqKSZidWZmZXJbRE9TX0ZTX1RZUEVfT0ZGU0VUXSwiRkFUIiwzKSkgewoJCS8qIG9rLCB3ZSBhc3N1bWUgd2UgYXJlIG9uIGEgUEJSIG9ubHkgKi8KCQljdXJfcGFydCA9IDE7CgkJcGFydF9vZmZzZXQ9MDsKCX0KCWVsc2UgewojaWYgKENPTkZJR19DT01NQU5EUyAmIENGR19DTURfSURFKSB8fCAoQ09ORklHX0NPTU1BTkRTICYgQ0ZHX0NNRF9TQ1NJKSB8fCBcCiAgICAoQ09ORklHX0NPTU1BTkRTICYgQ0ZHX0NNRF9VU0IpIHx8IChDT05GSUdfQ09NTUFORFMgJiBDRkdfQ01EX01NQykgfHwgZGVmaW5lZChDT05GSUdfU1lTVEVNQUNFKQoJCWRpc2tfcGFydGl0aW9uX3QgaW5mbzsKCQlpZighZ2V0X3BhcnRpdGlvbl9pbmZvKGRldl9kZXNjLCBwYXJ0X25vLCAmaW5mbykpIHsKCQkJcGFydF9vZmZzZXQgPSBpbmZvLnN0YXJ0OwoJCQljdXJfcGFydCA9IHBhcnRfbm87CgkJfQoJCWVsc2UgewoJCQlwcmludGYgKCIqKiBQYXJ0aXRpb24gJWQgbm90IHZhbGlkIG9uIGRldmljZSAlZCAqKlxuIixwYXJ0X25vLGRldl9kZXNjLT5kZXYpOwoJCQlyZXR1cm4gLTE7CgkJfQojZWxzZQoJCS8qIEZJWE1FIHdlIG5lZWQgdG8gZGV0ZXJtaW5lIHRoZSBzdGFydCBibG9jayBvZiB0aGUKCQkgKiBwYXJ0aXRpb24gd2hlcmUgdGhlIERPUyBGUyByZXNpZGVzLiBUaGlzIGNhbiBiZSBkb25lCgkJICogYnkgdXNpbmcgdGhlIGdldF9wYXJ0aXRpb25faW5mbyByb3V0aW5lLiBGb3IgdGhpcwoJCSAqIHB1cnBvc2UgdGhlIGxpYnBhcnQgbXVzdCBiZSBpbmNsdWRlZC4KCQkgKi8KCQlwYXJ0X29mZnNldD02MzsKCQkvL3BhcnRfb2Zmc2V0PTA7CgkJY3VyX3BhcnQgPSAxOwojZW5kaWYKCX0KCXJldHVybiAwOwp9CgoKLyoKICogR2V0IHRoZSBmaXJzdCBvY2N1cmVuY2Ugb2YgYSBkaXJlY3RvcnkgZGVsaW1pdGVyICgnLycgb3IgJ1wnKSBpbiBhIHN0cmluZy4KICogUmV0dXJuIGluZGV4IGludG8gc3RyaW5nIGlmIGZvdW5kLCAtMSBvdGhlcndpc2UuCiAqLwpzdGF0aWMgaW50CmRpcmRlbGltKGNoYXIgKnN0cikKewoJY2hhciAqc3RhcnQgPSBzdHI7CgoJd2hpbGUgKCpzdHIgIT0gJ1wwJykgewoJCWlmIChJU0RJUkRFTElNKCpzdHIpKSByZXR1cm4gc3RyIC0gc3RhcnQ7CgkJc3RyKys7Cgl9CglyZXR1cm4gLTE7Cn0KCgovKgogKiBNYXRjaCB2b2x1bWVfaW5mbyBmc190eXBlIHN0cmluZ3MuCiAqIFJldHVybiAwIG9uIG1hdGNoLCAtMSBvdGhlcndpc2UuCiAqLwpzdGF0aWMgaW50CmNvbXBhcmVfc2lnbihjaGFyICpzdHIxLCBjaGFyICpzdHIyKQp7CgljaGFyICplbmQgPSBzdHIxK1NJR05MRU47CgoJd2hpbGUgKHN0cjEgIT0gZW5kKSB7CgkJaWYgKCpzdHIxICE9ICpzdHIyKSB7CgkJCXJldHVybiAtMTsKCQl9CgkJc3RyMSsrOwoJCXN0cjIrKzsKCX0KCglyZXR1cm4gMDsKfQoKCi8qCiAqIEV4dHJhY3QgemVybyB0ZXJtaW5hdGVkIHNob3J0IG5hbWUgZnJvbSBhIGRpcmVjdG9yeSBlbnRyeS4KICovCnN0YXRpYyB2b2lkIGdldF9uYW1lIChkaXJfZW50cnkgKmRpcmVudCwgY2hhciAqc19uYW1lKQp7CgljaGFyICpwdHI7CgoJbWVtY3B5IChzX25hbWUsIGRpcmVudC0+bmFtZSwgOCk7CglzX25hbWVbOF0gPSAnXDAnOwoJcHRyID0gc19uYW1lOwoJd2hpbGUgKCpwdHIgJiYgKnB0ciAhPSAnICcpCgkJcHRyKys7CglpZiAoZGlyZW50LT5leHRbMF0gJiYgZGlyZW50LT5leHRbMF0gIT0gJyAnKSB7CgkJKnB0ciA9ICcuJzsKCQlwdHIrKzsKCQltZW1jcHkgKHB0ciwgZGlyZW50LT5leHQsIDMpOwoJCXB0clszXSA9ICdcMCc7CgkJd2hpbGUgKCpwdHIgJiYgKnB0ciAhPSAnICcpCgkJCXB0cisrOwoJfQoJKnB0ciA9ICdcMCc7CglpZiAoKnNfbmFtZSA9PSBERUxFVEVEX0ZMQUcpCgkJKnNfbmFtZSA9ICdcMCc7CgllbHNlIGlmICgqc19uYW1lID09IGFSSU5HKQoJCSpzX25hbWUgPSAn5Sc7Cglkb3duY2FzZSAoc19uYW1lKTsKfQoKLyoKICogR2V0IHRoZSBlbnRyeSBhdCBpbmRleCAnZW50cnknIGluIGEgRkFUICgxMi8xNi8zMikgdGFibGUuCiAqIE9uIGZhaWx1cmUgMHgwMCBpcyByZXR1cm5lZC4KICovCnN0YXRpYyBfX3UzMgpnZXRfZmF0ZW50KGZzZGF0YSAqbXlkYXRhLCBfX3UzMiBlbnRyeSkKewoJX191MzIgYnVmbnVtOwoJX191MzIgb2Zmc2V0OwoJX191MzIgcmV0ID0gMHgwMDsKCglzd2l0Y2ggKG15ZGF0YS0+ZmF0c2l6ZSkgewoJY2FzZSAzMjoKCQlidWZudW0gPSBlbnRyeSAvIEZBVDMyQlVGU0laRTsKCQlvZmZzZXQgPSBlbnRyeSAtIGJ1Zm51bSAqIEZBVDMyQlVGU0laRTsKCQlicmVhazsKCWNhc2UgMTY6CgkJYnVmbnVtID0gZW50cnkgLyBGQVQxNkJVRlNJWkU7CgkJb2Zmc2V0ID0gZW50cnkgLSBidWZudW0gKiBGQVQxNkJVRlNJWkU7CgkJYnJlYWs7CgljYXNlIDEyOgoJCWJ1Zm51bSA9IGVudHJ5IC8gRkFUMTJCVUZTSVpFOwoJCW9mZnNldCA9IGVudHJ5IC0gYnVmbnVtICogRkFUMTJCVUZTSVpFOwoJCWJyZWFrOwoKCWRlZmF1bHQ6CgkJLyogVW5zdXBwb3J0ZWQgRkFUIHNpemUgKi8KCQlyZXR1cm4gcmV0OwoJfQoJLyogUmVhZCBhIG5ldyBibG9jayBvZiBGQVQgZW50cmllcyBpbnRvIHRoZSBjYWNoZS4gKi8KCWlmIChidWZudW0gIT0gbXlkYXRhLT5mYXRidWZudW0pIHsKCQlpbnQgZ2V0c2l6ZSA9IEZBVEJVRlNJWkUvRlNfQkxPQ0tfU0laRTsKCQlfX3U4ICpidWZwdHIgPSAoX191OCAqKW15ZGF0YS0+ZmF0YnVmOwoJCV9fdTMyIGZhdGxlbmd0aCA9IG15ZGF0YS0+ZmF0bGVuZ3RoOwoJCV9fdTMyIHN0YXJ0YmxvY2sgPSBidWZudW0gKiBGQVRCVUZCTE9DS1M7CgoJCWZhdGxlbmd0aCAqPSBTRUNUT1JfU0laRTsJLyogV2Ugd2FudCBpdCBpbiBieXRlcyBub3cgKi8KCQlzdGFydGJsb2NrICs9IG15ZGF0YS0+ZmF0X3NlY3Q7CS8qIE9mZnNldCBmcm9tIHN0YXJ0IG9mIGRpc2sgKi8KCgkJaWYgKGdldHNpemUgPiBmYXRsZW5ndGgpIGdldHNpemUgPSBmYXRsZW5ndGg7CgkJaWYgKGRpc2tfcmVhZChzdGFydGJsb2NrLCBnZXRzaXplLCBidWZwdHIpIDwgMCkgewoJCQlGQVRfRFBSSU5UKCJFcnJvciByZWFkaW5nIEZBVCBibG9ja3NcbiIpOwoJCQlyZXR1cm4gcmV0OwoJCX0KCQlteWRhdGEtPmZhdGJ1Zm51bSA9IGJ1Zm51bTsKCX0KCgkvKiBHZXQgdGhlIGFjdHVhbCBlbnRyeSBmcm9tIHRoZSB0YWJsZSAqLwoJc3dpdGNoIChteWRhdGEtPmZhdHNpemUpIHsKCWNhc2UgMzI6CgkJcmV0ID0gRkFUMkNQVTMyKCgoX191MzIqKW15ZGF0YS0+ZmF0YnVmKVtvZmZzZXRdKTsKCQlicmVhazsKCWNhc2UgMTY6CgkJcmV0ID0gRkFUMkNQVTE2KCgoX191MTYqKW15ZGF0YS0+ZmF0YnVmKVtvZmZzZXRdKTsKCQlicmVhazsKCWNhc2UgMTI6IHsKCQlfX3UzMiBvZmYxNiA9IChvZmZzZXQqMykvNDsKCQlfX3UxNiB2YWwxLCB2YWwyOwoKCQlzd2l0Y2ggKG9mZnNldCAmIDB4MykgewoJCWNhc2UgMDoKCQkJcmV0ID0gRkFUMkNQVTE2KCgoX191MTYqKW15ZGF0YS0+ZmF0YnVmKVtvZmYxNl0pOwoJCQlyZXQgJj0gMHhmZmY7CgkJCWJyZWFrOwoJCWNhc2UgMToKCQkJdmFsMSA9IEZBVDJDUFUxNigoKF9fdTE2KilteWRhdGEtPmZhdGJ1Zilbb2ZmMTZdKTsKCQkJdmFsMSAmPSAweGYwMDA7CgkJCXZhbDIgPSBGQVQyQ1BVMTYoKChfX3UxNiopbXlkYXRhLT5mYXRidWYpW29mZjE2KzFdKTsKCQkJdmFsMiAmPSAweDAwZmY7CgkJCXJldCA9ICh2YWwyIDw8IDQpIHwgKHZhbDEgPj4gMTIpOwoJCQlicmVhazsKCQljYXNlIDI6CgkJCXZhbDEgPSBGQVQyQ1BVMTYoKChfX3UxNiopbXlkYXRhLT5mYXRidWYpW29mZjE2XSk7CgkJCXZhbDEgJj0gMHhmZjAwOwoJCQl2YWwyID0gRkFUMkNQVTE2KCgoX191MTYqKW15ZGF0YS0+ZmF0YnVmKVtvZmYxNisxXSk7CgkJCXZhbDIgJj0gMHgwMDBmOwoJCQlyZXQgPSAodmFsMiA8PCA4KSB8ICh2YWwxID4+IDgpOwoJCQlicmVhazsKCQljYXNlIDM6CgkJCXJldCA9IEZBVDJDUFUxNigoKF9fdTE2KilteWRhdGEtPmZhdGJ1Zilbb2ZmMTZdKTs7CgkJCXJldCA9IChyZXQgJiAweGZmZjApID4+IDQ7CgkJCWJyZWFrOwoJCWRlZmF1bHQ6CgkJCWJyZWFrOwoJCX0KCX0KCWJyZWFrOwoJfQoJRkFUX0RQUklOVCgicmV0OiAlZCwgb2Zmc2V0OiAlZFxuIiwgcmV0LCBvZmZzZXQpOwoKCXJldHVybiByZXQ7Cn0KCgovKgogKiBSZWFkIGF0IG1vc3QgJ3NpemUnIGJ5dGVzIGZyb20gdGhlIHNwZWNpZmllZCBjbHVzdGVyIGludG8gJ2J1ZmZlcicuCiAqIFJldHVybiAwIG9uIHN1Y2Nlc3MsIC0xIG90aGVyd2lzZS4KICovCnN0YXRpYyBpbnQKZ2V0X2NsdXN0ZXIoZnNkYXRhICpteWRhdGEsIF9fdTMyIGNsdXN0bnVtLCBfX3U4ICpidWZmZXIsIHVuc2lnbmVkIGxvbmcgc2l6ZSkKewoJaW50IGlkeCA9IDA7CglfX3UzMiBzdGFydHNlY3Q7CgoJaWYgKGNsdXN0bnVtID4gMCkgewoJCXN0YXJ0c2VjdCA9IG15ZGF0YS0+ZGF0YV9iZWdpbiArIGNsdXN0bnVtKm15ZGF0YS0+Y2x1c3Rfc2l6ZTsKCX0gZWxzZSB7CgkJc3RhcnRzZWN0ID0gbXlkYXRhLT5yb290ZGlyX3NlY3Q7Cgl9CgoJaWYgKGRpc2tfcmVhZChzdGFydHNlY3QsIHNpemUvRlNfQkxPQ0tfU0laRSAsIGJ1ZmZlcikgPCAwKSB7CgkJRkFUX0RQUklOVCgiRXJyb3IgcmVhZGluZyBkYXRhXG4iKTsKCQlyZXR1cm4gLTE7Cgl9CglpZihzaXplICUgRlNfQkxPQ0tfU0laRSkgewoJCV9fdTggdG1wYnVmW0ZTX0JMT0NLX1NJWkVdOwoJCWlkeD0gc2l6ZS9GU19CTE9DS19TSVpFOwoJCWlmIChkaXNrX3JlYWQoc3RhcnRzZWN0ICsgaWR4LCAxLCB0bXBidWYpIDwgMCkgewoJCQlGQVRfRFBSSU5UKCJFcnJvciByZWFkaW5nIGRhdGFcbiIpOwoJCQlyZXR1cm4gLTE7CgkJfQoJCWJ1ZmZlciArPSBpZHgqRlNfQkxPQ0tfU0laRTsKCgkJbWVtY3B5KGJ1ZmZlciwgdG1wYnVmLCBzaXplICUgRlNfQkxPQ0tfU0laRSk7CgkJcmV0dXJuIDA7Cgl9CgoJcmV0dXJuIDA7Cn0KCgovKgogKiBSZWFkIGF0IG1vc3QgJ21heHNpemUnIGJ5dGVzIGZyb20gdGhlIGZpbGUgYXNzb2NpYXRlZCB3aXRoICdkZW50cHRyJwogKiBpbnRvICdidWZmZXInLgogKiBSZXR1cm4gdGhlIG51bWJlciBvZiBieXRlcyByZWFkIG9yIC0xIG9uIGZhdGFsIGVycm9ycy4KICovCnN0YXRpYyBsb25nCmdldF9jb250ZW50cyhmc2RhdGEgKm15ZGF0YSwgZGlyX2VudHJ5ICpkZW50cHRyLCBfX3U4ICpidWZmZXIsCgkgICAgIHVuc2lnbmVkIGxvbmcgbWF4c2l6ZSkKewoJdW5zaWduZWQgbG9uZyBmaWxlc2l6ZSA9IEZBVDJDUFUzMihkZW50cHRyLT5zaXplKSwgZ290c2l6ZSA9IDA7Cgl1bnNpZ25lZCBpbnQgYnl0ZXNwZXJjbHVzdCA9IG15ZGF0YS0+Y2x1c3Rfc2l6ZSAqIFNFQ1RPUl9TSVpFOwoJX191MzIgY3VyY2x1c3QgPSBTVEFSVChkZW50cHRyKTsKCV9fdTMyIGVuZGNsdXN0LCBuZXdjbHVzdDsKCXVuc2lnbmVkIGxvbmcgYWN0c2l6ZTsKCglGQVRfRFBSSU5UKCJGaWxlc2l6ZTogJWxkIGJ5dGVzXG4iLCBmaWxlc2l6ZSk7CgoJaWYgKG1heHNpemUgPiAwICYmIGZpbGVzaXplID4gbWF4c2l6ZSkgZmlsZXNpemUgPSBtYXhzaXplOwoKCUZBVF9EUFJJTlQoIlJlYWRpbmc6ICVsZCBieXRlc1xuIiwgZmlsZXNpemUpOwoKCWFjdHNpemU9Ynl0ZXNwZXJjbHVzdDsKCWVuZGNsdXN0PWN1cmNsdXN0OwoJZG8gewoJCS8qIHNlYXJjaCBmb3IgY29uc2VjdXRpdmUgY2x1c3RlcnMgKi8KCQl3aGlsZShhY3RzaXplIDwgZmlsZXNpemUpIHsKCQkJbmV3Y2x1c3QgPSBnZXRfZmF0ZW50KG15ZGF0YSwgZW5kY2x1c3QpOwoJCQlpZigobmV3Y2x1c3QgLTEpIT1lbmRjbHVzdCkKCQkJCWdvdG8gZ2V0aXQ7CgkJCWlmIChuZXdjbHVzdCA8PSAweDAwMDEgfHwgbmV3Y2x1c3QgPj0gMHhmZmYwKSB7CgkJCQlGQVRfRFBSSU5UKCJjdXJjbHVzdDogMHgleFxuIiwgbmV3Y2x1c3QpOwoJCQkJRkFUX0RQUklOVCgiSW52YWxpZCBGQVQgZW50cnlcbiIpOwoJCQkJcmV0dXJuIGdvdHNpemU7CgkJCX0KCQkJZW5kY2x1c3Q9bmV3Y2x1c3Q7CgkJCWFjdHNpemUrPSBieXRlc3BlcmNsdXN0OwoJCX0KCQkvKiBhY3RzaXplID49IGZpbGUgc2l6ZSAqLwoJCWFjdHNpemUgLT0gYnl0ZXNwZXJjbHVzdDsKCQkvKiBnZXQgcmVtYWluaW5nIGNsdXN0ZXJzICovCgkJaWYgKGdldF9jbHVzdGVyKG15ZGF0YSwgY3VyY2x1c3QsIGJ1ZmZlciwgKGludClhY3RzaXplKSAhPSAwKSB7CgkJCUZBVF9FUlJPUigiRXJyb3IgcmVhZGluZyBjbHVzdGVyXG4iKTsKCQkJcmV0dXJuIC0xOwoJCX0KCQkvKiBnZXQgcmVtYWluaW5nIGJ5dGVzICovCgkJZ290c2l6ZSArPSAoaW50KWFjdHNpemU7CgkJZmlsZXNpemUgLT0gYWN0c2l6ZTsKCQlidWZmZXIgKz0gYWN0c2l6ZTsKCQlhY3RzaXplPSBmaWxlc2l6ZTsKCQlpZiAoZ2V0X2NsdXN0ZXIobXlkYXRhLCBlbmRjbHVzdCwgYnVmZmVyLCAoaW50KWFjdHNpemUpICE9IDApIHsKCQkJRkFUX0VSUk9SKCJFcnJvciByZWFkaW5nIGNsdXN0ZXJcbiIpOwoJCQlyZXR1cm4gLTE7CgkJfQoJCWdvdHNpemUrPWFjdHNpemU7CgkJcmV0dXJuIGdvdHNpemU7CmdldGl0OgoJCWlmIChnZXRfY2x1c3RlcihteWRhdGEsIGN1cmNsdXN0LCBidWZmZXIsIChpbnQpYWN0c2l6ZSkgIT0gMCkgewoJCQlGQVRfRVJST1IoIkVycm9yIHJlYWRpbmcgY2x1c3RlclxuIik7CgkJCXJldHVybiAtMTsKCQl9CgkJZ290c2l6ZSArPSAoaW50KWFjdHNpemU7CgkJZmlsZXNpemUgLT0gYWN0c2l6ZTsKCQlidWZmZXIgKz0gYWN0c2l6ZTsKCQljdXJjbHVzdCA9IGdldF9mYXRlbnQobXlkYXRhLCBlbmRjbHVzdCk7CgkJaWYgKGN1cmNsdXN0IDw9IDB4MDAwMSB8fCBjdXJjbHVzdCA+PSAweGZmZjApIHsKCQkJRkFUX0RQUklOVCgiY3VyY2x1c3Q6IDB4JXhcbiIsIGN1cmNsdXN0KTsKCQkJRkFUX0VSUk9SKCJJbnZhbGlkIEZBVCBlbnRyeVxuIik7CgkJCXJldHVybiBnb3RzaXplOwoJCX0KCQlhY3RzaXplPWJ5dGVzcGVyY2x1c3Q7CgkJZW5kY2x1c3Q9Y3VyY2x1c3Q7Cgl9IHdoaWxlICgxKTsKfQoKCiNpZmRlZiBDT05GSUdfU1VQUE9SVF9WRkFUCiNpZiAwCi8qCiAqIEV4dHJhY3QgdGhlIGZpbGUgbmFtZSBpbmZvcm1hdGlvbiBmcm9tICdzbG90cHRyJyBpbnRvICdsX25hbWUnLAogKiBzdGFydGluZyBhdCBsX25hbWVbKmlkeF0uCiAqIFJldHVybiAxIGlmIHRlcm1pbmF0b3IgKHplcm8gYnl0ZSkgaXMgZm91bmQsIDAgb3RoZXJ3aXNlLgogKi8Kc3RhdGljIGludApzbG90MnN0cihkaXJfc2xvdCAqc2xvdHB0ciwgY2hhciAqbF9uYW1lLCBpbnQgKmlkeCkKewoJaW50IGo7CgoJZm9yIChqID0gMDsgaiA8PSA4OyBqICs9IDIpIHsKCQlsX25hbWVbKmlkeF0gPSBzbG90cHRyLT5uYW1lMF80W2pdOwoJCWlmIChsX25hbWVbKmlkeF0gPT0gMHgwMCkgcmV0dXJuIDE7CgkJKCppZHgpKys7Cgl9Cglmb3IgKGogPSAwOyBqIDw9IDEwOyBqICs9IDIpIHsKCQlsX25hbWVbKmlkeF0gPSBzbG90cHRyLT5uYW1lNV8xMFtqXTsKCQlpZiAobF9uYW1lWyppZHhdID09IDB4MDApIHJldHVybiAxOwoJCSgqaWR4KSsrOwoJfQoJZm9yIChqID0gMDsgaiA8PSAyOyBqICs9IDIpIHsKCQlsX25hbWVbKmlkeF0gPSBzbG90cHRyLT5uYW1lMTFfMTJbal07CgkJaWYgKGxfbmFtZVsqaWR4XSA9PSAweDAwKSByZXR1cm4gMTsKCQkoKmlkeCkrKzsKCX0KCglyZXR1cm4gMDsKfQojZW5kaWYKLyogQ2FsY3VsYXRlIHNob3J0IG5hbWUgY2hlY2tzdW0gKi8Kc3RhdGljIF9fdTgKbWtja3N1bShjb25zdCBjaGFyICpzdHIpCnsKCWludCBpOwoJX191OCByZXQgPSAwOwoKCWZvciAoaSA9IDA7IGkgPCAxMTsgaSsrKSB7CgkJcmV0ID0gKCgocmV0JjEpPDw3KXwoKHJldCYweGZlKT4+MSkpICsgc3RyW2ldOwoJfQoKCXJldHVybiByZXQ7Cn0KI2VuZGlmCgoKLyoKICogR2V0IHRoZSBkaXJlY3RvcnkgZW50cnkgYXNzb2NpYXRlZCB3aXRoICdmaWxlbmFtZScgZnJvbSB0aGUgZGlyZWN0b3J5CiAqIHN0YXJ0aW5nIGF0ICdzdGFydHNlY3QnCiAqLwoKCnN0YXRpYyBkaXJfZW50cnkgKmdldF9kZW50ZnJvbWRpciAoZnNkYXRhICogbXlkYXRhLCBpbnQgc3RhcnRzZWN0LAoJCQkJICAgY2hhciAqZmlsZW5hbWUsIGRpcl9lbnRyeSAqIHJldGRlbnQsCgkJCQkgICBpbnQgZG9scykKewoJcmV0dXJuIE5VTEw7Cn0KCiNpZiAwCl9fdTggZ2V0X2RlbnRmcm9tZGlyX2Jsb2NrW01BWF9DTFVTVFNJWkVdOwpzdGF0aWMgZGlyX2VudHJ5ICpnZXRfZGVudGZyb21kaXIgKGZzZGF0YSAqIG15ZGF0YSwgaW50IHN0YXJ0c2VjdCwKCQkJCSAgIGNoYXIgKmZpbGVuYW1lLCBkaXJfZW50cnkgKiByZXRkZW50LAoJCQkJICAgaW50IGRvbHMpCnsKICAgIF9fdTE2IHByZXZja3N1bSA9IDB4ZmZmZjsKICAgIF9fdTMyIGN1cmNsdXN0ID0gU1RBUlQgKHJldGRlbnQpOwogICAgaW50IGZpbGVzID0gMCwgZGlycyA9IDA7CgogICAgd2hpbGUgKDEpIHsKCWRpcl9lbnRyeSAqZGVudHB0cjsKCWludCBpOwoKCWlmIChnZXRfY2x1c3RlciAobXlkYXRhLCBjdXJjbHVzdCwgZ2V0X2RlbnRmcm9tZGlyX2Jsb2NrLAoJCSBteWRhdGEtPmNsdXN0X3NpemUgKiBTRUNUT1JfU0laRSkgIT0gMCkgewoJICAgIEZBVF9EUFJJTlQgKCJFcnJvcjogcmVhZGluZyBkaXJlY3RvcnkgYmxvY2tcbiIpOwoJICAgIHJldHVybiBOVUxMOwoJfQoJZGVudHB0ciA9IChkaXJfZW50cnkgKikgZ2V0X2RlbnRmcm9tZGlyX2Jsb2NrOwoJZm9yIChpID0gMDsgaSA8IERJUkVOVFNQRVJDTFVTVDsgaSsrKSB7CgkgICAgY2hhciBzX25hbWVbMTRdLCBsX25hbWVbMjU2XTsKCgkgICAgbF9uYW1lWzBdID0gJ1wwJzsKCSAgICBpZiAoZGVudHB0ci0+bmFtZVswXSA9PSBERUxFVEVEX0ZMQUcpIHsKCQkgICAgZGVudHB0cisrOwoJCSAgICBjb250aW51ZTsKCSAgICB9CgkgICAgaWYgKChkZW50cHRyLT5hdHRyICYgQVRUUl9WT0xVTUUpKSB7CgkJICAgIC8qIFZvbHVtZSBsYWJlbCBvciBWRkFUIGVudHJ5ICovCgkJICAgIGRlbnRwdHIrKzsKCQkgICAgY29udGludWU7CgkgICAgfQoJICAgIGlmIChkZW50cHRyLT5uYW1lWzBdID09IDApIHsKCQlpZiAoZG9scykgewoJCSAgICBwcmludGYgKCJcbiVkIGZpbGUocyksICVkIGRpcihzKVxuXG4iLCBmaWxlcywgZGlycyk7CgkJfQoJCUZBVF9EUFJJTlQgKCJEZW50bmFtZSA9PSBOVUxMIC0gJWRcbiIsIGkpOwoJCXJldHVybiBOVUxMOwoJICAgIH0KI2lmZGVmIENPTkZJR19TVVBQT1JUX1ZGQVQKCSAgICBpZiAoZG9scyAmJiBta2Nrc3VtIChkZW50cHRyLT5uYW1lKSA9PSBwcmV2Y2tzdW0pIHsKCQlkZW50cHRyKys7CgkJY29udGludWU7CgkgICAgfQojZW5kaWYKCSAgICBnZXRfbmFtZSAoZGVudHB0ciwgc19uYW1lKTsKCSAgICBpZiAoZG9scykgewoJCWludCBpc2RpciA9IChkZW50cHRyLT5hdHRyICYgQVRUUl9ESVIpOwoJCWNoYXIgZGlyYzsKCQlpbnQgZG9pdCA9IDA7CgoJCWlmIChpc2RpcikgewoJCSAgICBkaXJzKys7CgkJICAgIGRpcmMgPSAnLyc7CgkJICAgIGRvaXQgPSAxOwoJCX0gZWxzZSB7CgkJICAgIGRpcmMgPSAnICc7CgkJICAgIGlmIChzX25hbWVbMF0gIT0gMCkgewoJCQlmaWxlcysrOwoJCQlkb2l0ID0gMTsKCQkgICAgfQoJCX0KCQlpZiAoZG9pdCkgewoJCSAgICBpZiAoZGlyYyA9PSAnICcpIHsKCQkJcHJpbnRmICgiICU4bGQgICAlcyVjXG4iLAoJCQkJKGxvbmcpIEZBVDJDUFUzMiAoZGVudHB0ci0+c2l6ZSksIHNfbmFtZSwKCQkJCWRpcmMpOwoJCSAgICB9IGVsc2UgewoJCQlwcmludGYgKCIgICAgICAgICAgICAlcyVjXG4iLCBzX25hbWUsIGRpcmMpOwoJCSAgICB9CgkJfQoJCWRlbnRwdHIrKzsKCQljb250aW51ZTsKCSAgICB9CgkgICAgaWYgKHN0cmNtcCAoZmlsZW5hbWUsIHNfbmFtZSkgJiYgc3RyY21wIChmaWxlbmFtZSwgbF9uYW1lKSkgewoJCUZBVF9EUFJJTlQgKCJNaXNtYXRjaDogfCVzfCVzfFxuIiwgc19uYW1lLCBsX25hbWUpOwoJCWRlbnRwdHIrKzsKCQljb250aW51ZTsKCSAgICB9CgkgICAgbWVtY3B5IChyZXRkZW50LCBkZW50cHRyLCBzaXplb2YgKGRpcl9lbnRyeSkpOwoKCSAgICBGQVRfRFBSSU5UICgiRGVudE5hbWU6ICVzIiwgc19uYW1lKTsKCSAgICBGQVRfRFBSSU5UICgiLCBzdGFydDogMHgleCIsIFNUQVJUIChkZW50cHRyKSk7CgkgICAgRkFUX0RQUklOVCAoIiwgc2l6ZTogIDB4JXggJXNcbiIsCgkJCUZBVDJDUFUzMiAoZGVudHB0ci0+c2l6ZSksCgkJCShkZW50cHRyLT5hdHRyICYgQVRUUl9ESVIpID8gIihESVIpIiA6ICIiKTsKCgkgICAgcmV0dXJuIHJldGRlbnQ7Cgl9CgljdXJjbHVzdCA9IGdldF9mYXRlbnQgKG15ZGF0YSwgY3VyY2x1c3QpOwoJaWYgKGN1cmNsdXN0IDw9IDB4MDAwMSB8fCBjdXJjbHVzdCA+PSAweGZmZjApIHsKCSAgICBGQVRfRFBSSU5UICgiY3VyY2x1c3Q6IDB4JXhcbiIsIGN1cmNsdXN0KTsKCSAgICBGQVRfRVJST1IgKCJJbnZhbGlkIEZBVCBlbnRyeVxuIik7CgkgICAgcmV0dXJuIE5VTEw7Cgl9CiAgICB9CgogICAgcmV0dXJuIE5VTEw7Cn0KI2VuZGlmCgoKLyoKICogUmVhZCBib290IHNlY3RvciBhbmQgdm9sdW1lIGluZm8gZnJvbSBhIEZBVCBmaWxlc3lzdGVtCiAqLwpzdGF0aWMgaW50CnJlYWRfYm9vdHNlY3RhbmR2aShib290X3NlY3RvciAqYnMsIHZvbHVtZV9pbmZvICp2b2xpbmZvLCBpbnQgKmZhdHNpemUpCnsKCV9fdTggYmxvY2tbRlNfQkxPQ0tfU0laRV07Cgl2b2x1bWVfaW5mbyAqdmlzdGFydDsKCglwcmludGYoIlJlYWRpbmcgYm9vdCBzZWN0b3JcbiIpOwoKCWlmIChkaXNrX3JlYWQoMCwgMSwgYmxvY2spIDwgMCkgewoJCUZBVF9EUFJJTlQoIkVycm9yOiByZWFkaW5nIGJsb2NrXG4iKTsKCQlyZXR1cm4gLTE7Cgl9CgoJbWVtY3B5KGJzLCBibG9jaywgc2l6ZW9mKGJvb3Rfc2VjdG9yKSk7Cglicy0+cmVzZXJ2ZWQJPSBGQVQyQ1BVMTYoYnMtPnJlc2VydmVkKTsKCWJzLT5mYXRfbGVuZ3RoCT0gRkFUMkNQVTE2KGJzLT5mYXRfbGVuZ3RoKTsKCWJzLT5zZWNzX3RyYWNrCT0gRkFUMkNQVTE2KGJzLT5zZWNzX3RyYWNrKTsKCWJzLT5oZWFkcwk9IEZBVDJDUFUxNihicy0+aGVhZHMpOwojaWYgMCAvKiBVTlVTRUQgKi8KCWJzLT5oaWRkZW4JPSBGQVQyQ1BVMzIoYnMtPmhpZGRlbik7CiNlbmRpZgoJYnMtPnRvdGFsX3NlY3QJPSBGQVQyQ1BVMzIoYnMtPnRvdGFsX3NlY3QpOwoKCS8qIEZBVDMyIGVudHJpZXMgKi8KCWlmIChicy0+ZmF0X2xlbmd0aCA9PSAwKSB7CgkJLyogQXNzdW1lIEZBVDMyICovCgkJYnMtPmZhdDMyX2xlbmd0aCA9IEZBVDJDUFUzMihicy0+ZmF0MzJfbGVuZ3RoKTsKCQlicy0+ZmxhZ3MJID0gRkFUMkNQVTE2KGJzLT5mbGFncyk7CgkJYnMtPnJvb3RfY2x1c3RlciA9IEZBVDJDUFUzMihicy0+cm9vdF9jbHVzdGVyKTsKCQlicy0+aW5mb19zZWN0b3IgID0gRkFUMkNQVTE2KGJzLT5pbmZvX3NlY3Rvcik7CgkJYnMtPmJhY2t1cF9ib290ICA9IEZBVDJDUFUxNihicy0+YmFja3VwX2Jvb3QpOwoJCXZpc3RhcnQgPSAodm9sdW1lX2luZm8qKSAoYmxvY2sgKyBzaXplb2YoYm9vdF9zZWN0b3IpKTsKCQkqZmF0c2l6ZSA9IDMyOwoJfSBlbHNlIHsKCQl2aXN0YXJ0ID0gKHZvbHVtZV9pbmZvKikgJihicy0+ZmF0MzJfbGVuZ3RoKTsKCQkqZmF0c2l6ZSA9IDA7Cgl9CgltZW1jcHkodm9saW5mbywgdmlzdGFydCwgc2l6ZW9mKHZvbHVtZV9pbmZvKSk7CgoJLyogVGVybWluYXRlIGZzX3R5cGUgc3RyaW5nLiBXcml0aW5nIHBhc3QgdGhlIGVuZCBvZiB2aXN0YXJ0CgkgICBpcyBvayAtIGl0J3MganVzdCB0aGUgYnVmZmVyLiAqLwoJdmlzdGFydC0+ZnNfdHlwZVs3XSA9ICdcMCc7CgoJaWYgKCpmYXRzaXplID09IDMyKSB7CgkJaWYgKGNvbXBhcmVfc2lnbihGQVQzMl9TSUdOLCB2aXN0YXJ0LT5mc190eXBlKSA9PSAwKSB7CgkJCXJldHVybiAwOwoJCX0KCX0gZWxzZSB7CgkJaWYgKGNvbXBhcmVfc2lnbihGQVQxMl9TSUdOLCB2aXN0YXJ0LT5mc190eXBlKSA9PSAwKSB7CgkJCSpmYXRzaXplID0gMTI7CgkJCXJldHVybiAwOwoJCX0KCQlpZiAoY29tcGFyZV9zaWduKEZBVDE2X1NJR04sIHZpc3RhcnQtPmZzX3R5cGUpID09IDApIHsKCQkJKmZhdHNpemUgPSAxNjsKCQkJcmV0dXJuIDA7CgkJfQoJfQoKCUZBVF9EUFJJTlQoIkVycm9yOiBicm9rZW4gZnNfdHlwZSBzaWduXG4iKTsKCXJldHVybiAtMTsKfQoKI2lmIDAKX191OCBkb19mYXRfcmVhZF9ibG9ja1tNQVhfQ0xVU1RTSVpFXTsgIC8qIEJsb2NrIGJ1ZmZlciAqLwojZW5kaWYKCl9fdTggKmZuYW1lY29weSA9IChfX3U4ICopMHg4MDUwMDAwMDsKX191OCAqZG9fZmF0X3JlYWRfYmxvY2sgPSAoX191OCAqKTB4ODA1MDA4ODA7Cgpib290X3NlY3RvciBiczsKdm9sdW1lX2luZm8gdm9saW5mbzsKZnNkYXRhIGRhdGFibG9jazsKCmxvbmcKZG9fZmF0X3JlYWQoY29uc3QgY2hhciAqZmlsZW5hbWUsIHZvaWQgKmJ1ZmZlciwgdW5zaWduZWQgbG9uZyBtYXhzaXplLAoJICAgICBpbnQgZG9scykKewojaWYgQ09ORklHX05JT1MgLyogTklPUyBDUFUgY2Fubm90IGFjY2VzcyBiaWcgYXV0b21hdGljIGFycmF5cyAqLwogICAgc3RhdGljCiNlbmRpZgogICAgZnNkYXRhICpteWRhdGEgPSAmZGF0YWJsb2NrOwogICAgZGlyX2VudHJ5ICpkZW50cHRyOwogICAgX191MTYgcHJldmNrc3VtID0gMHhmZmZmOwogICAgY2hhciAqc3VibmFtZSA9ICIiOwogICAgaW50IHJvb3RkaXJfc2l6ZSwgY3Vyc2VjdDsKICAgIGludCBpZHgsIGlzZGlyID0gMDsKICAgIGludCBmaWxlcyA9IDAsIGRpcnMgPSAwOwogICAgbG9uZyByZXQgPSAwOwogICAgaW50IGZpcnN0dGltZTsKCiAgICBpZiAocmVhZF9ib290c2VjdGFuZHZpICgmYnMsICZ2b2xpbmZvLCAmbXlkYXRhLT5mYXRzaXplKSkgewoJcHJpbnRmICgiRXJyb3I6IHJlYWRpbmcgYm9vdCBzZWN0b3JcbiIpOwoJcmV0dXJuIC0xOwogICAgfQogICAgaWYgKG15ZGF0YS0+ZmF0c2l6ZSA9PSAzMikgewoJbXlkYXRhLT5mYXRsZW5ndGggPSBicy5mYXQzMl9sZW5ndGg7CiAgICB9IGVsc2UgewoJbXlkYXRhLT5mYXRsZW5ndGggPSBicy5mYXRfbGVuZ3RoOwogICAgfQogICAgbXlkYXRhLT5mYXRfc2VjdCA9IGJzLnJlc2VydmVkOwogICAgY3Vyc2VjdCA9IG15ZGF0YS0+cm9vdGRpcl9zZWN0CgkgICAgPSBteWRhdGEtPmZhdF9zZWN0ICsgbXlkYXRhLT5mYXRsZW5ndGggKiBicy5mYXRzOwogICAgbXlkYXRhLT5jbHVzdF9zaXplID0gYnMuY2x1c3Rlcl9zaXplOwogICAgaWYgKG15ZGF0YS0+ZmF0c2l6ZSA9PSAzMikgewoJcm9vdGRpcl9zaXplID0gbXlkYXRhLT5jbHVzdF9zaXplOwoJbXlkYXRhLT5kYXRhX2JlZ2luID0gbXlkYXRhLT5yb290ZGlyX3NlY3QgICAvKiArIHJvb3RkaXJfc2l6ZSAqLwoJCS0gKG15ZGF0YS0+Y2x1c3Rfc2l6ZSAqIDIpOwogICAgfSBlbHNlIHsKCXJvb3RkaXJfc2l6ZSA9ICgoYnMuZGlyX2VudHJpZXNbMV0gKiAoaW50KSAyNTYgKyBicy5kaXJfZW50cmllc1swXSkKCQkJKiBzaXplb2YgKGRpcl9lbnRyeSkpIC8gU0VDVE9SX1NJWkU7CglteWRhdGEtPmRhdGFfYmVnaW4gPSBteWRhdGEtPnJvb3RkaXJfc2VjdCArIHJvb3RkaXJfc2l6ZQoJCS0gKG15ZGF0YS0+Y2x1c3Rfc2l6ZSAqIDIpOwogICAgfQogICAgbXlkYXRhLT5mYXRidWZudW0gPSAtMTsKCiAgICBGQVRfRFBSSU5UICgiRkFUJWQsIGZhdGxlbmd0aDogJWRcbiIsIG15ZGF0YS0+ZmF0c2l6ZSwKCQlteWRhdGEtPmZhdGxlbmd0aCk7CiAgICBGQVRfRFBSSU5UICgiUm9vdGRpciBiZWdpbnMgYXQgc2VjdG9yOiAlZCwgb2Zmc2V0OiAleCwgc2l6ZTogJWRcbiIKCQkiRGF0YSBiZWdpbnMgYXQ6ICVkXG4iLAoJCW15ZGF0YS0+cm9vdGRpcl9zZWN0LCBteWRhdGEtPnJvb3RkaXJfc2VjdCAqIFNFQ1RPUl9TSVpFLAoJCXJvb3RkaXJfc2l6ZSwgbXlkYXRhLT5kYXRhX2JlZ2luKTsKICAgIEZBVF9EUFJJTlQgKCJDbHVzdGVyIHNpemU6ICVkXG4iLCBteWRhdGEtPmNsdXN0X3NpemUpOwoKICAgIC8qICJjd2QiIGlzIGFsd2F5cyB0aGUgcm9vdC4uLiAqLwogICAgd2hpbGUgKElTRElSREVMSU0gKCpmaWxlbmFtZSkpCglmaWxlbmFtZSsrOwogICAgLyogTWFrZSBhIGNvcHkgb2YgdGhlIGZpbGVuYW1lIGFuZCBjb252ZXJ0IGl0IHRvIGxvd2VyY2FzZSAqLwogICAgc3RyY3B5KChjaGFyICopZm5hbWVjb3B5LCBmaWxlbmFtZSk7CiAgICBkb3duY2FzZSgoY2hhciAqKWZuYW1lY29weSk7CiAgICBpZiAoKmZuYW1lY29weSA9PSAnXDAnKSB7CglpZiAoIWRvbHMpewoJCXByaW50ZigiXG4gbm90IHRoZXJlXG4iKTsKCSAgICByZXR1cm4gLTE7Cgl9Cglkb2xzID0gTFNfUk9PVDsKICAgIH0gZWxzZSBpZigoaWR4ID0gZGlyZGVsaW0oKGNoYXIgKilmbmFtZWNvcHkpKSA+PSAwKSB7Cglpc2RpciA9IDE7CglmbmFtZWNvcHlbaWR4XSA9ICdcMCc7CglzdWJuYW1lID0gKGNoYXIgKilmbmFtZWNvcHkgKyBpZHggKyAxOwoJLyogSGFuZGxlIG11bHRpcGxlIGRlbGltaXRlcnMgKi8KCXdoaWxlIChJU0RJUkRFTElNICgqc3VibmFtZSkpCgkgICAgc3VibmFtZSsrOwogICAgfSBlbHNlIGlmIChkb2xzKSB7Cglpc2RpciA9IDE7CiAgICB9CgogICAgd2hpbGUgKDEpIHsKCWludCBpOwoKCWlmIChkaXNrX3JlYWQgKGN1cnNlY3QsIG15ZGF0YS0+Y2x1c3Rfc2l6ZSwgZG9fZmF0X3JlYWRfYmxvY2spIDwgMCkgewoJICAgIHByaW50ZiAoIkVycm9yOiByZWFkaW5nIHJvb3RkaXIgYmxvY2tcbiIpOwoJICAgIHJldHVybiAtMTsKCX0KCWRlbnRwdHIgPSAoZGlyX2VudHJ5ICopIGRvX2ZhdF9yZWFkX2Jsb2NrOwoJZm9yIChpID0gMDsgaSA8IERJUkVOVFNQRVJCTE9DSzsgaSsrKSB7CgkgICAgY2hhciBzX25hbWVbMTRdLCBsX25hbWVbMjU2XTsKCgkgICAgbF9uYW1lWzBdID0gJ1wwJzsKCSAgICBpZiAoKGRlbnRwdHItPmF0dHIgJiBBVFRSX1ZPTFVNRSkpIHsKCQkgICAgLyogVm9sdW1lIGxhYmVsIG9yIFZGQVQgZW50cnkgKi8KCQkgICAgZGVudHB0cisrOwoJCSAgICBjb250aW51ZTsKCSAgICB9IGVsc2UgaWYgKGRlbnRwdHItPm5hbWVbMF0gPT0gMCkgewoJCUZBVF9EUFJJTlQgKCJSb290RGVudG5hbWUgPT0gTlVMTCAtICVkXG4iLCBpKTsKCQlpZiAoZG9scyA9PSBMU19ST09UKSB7CgkJICAgIHByaW50ZiAoIlxuJWQgZmlsZShzKSwgJWQgZGlyKHMpXG5cbiIsIGZpbGVzLCBkaXJzKTsKCQkgICAgcmV0dXJuIDA7CgkJfQoJCXJldHVybiAtMTsKCSAgICB9CiNpZmRlZiBDT05GSUdfU1VQUE9SVF9WRkFUCgkgICAgZWxzZSBpZiAoZG9scyA9PSBMU19ST09UCgkJICAgICAmJiBta2Nrc3VtIChkZW50cHRyLT5uYW1lKSA9PSBwcmV2Y2tzdW0pIHsKCQlkZW50cHRyKys7CgkJY29udGludWU7CgkgICAgfQojZW5kaWYKCSAgICBnZXRfbmFtZSAoZGVudHB0ciwgc19uYW1lKTsKCSAgICBpZiAoZG9scyA9PSBMU19ST09UKSB7CgkJaW50IGlzZGlyID0gKGRlbnRwdHItPmF0dHIgJiBBVFRSX0RJUik7CgkJY2hhciBkaXJjOwoJCWludCBkb2l0ID0gMDsKCgkJaWYgKGlzZGlyKSB7CgkJICAgIGRpcmMgPSAnLyc7CgkJICAgIGlmIChzX25hbWVbMF0gIT0gMCkgewoJCQlkaXJzKys7CgkJCWRvaXQgPSAxOwoJCSAgICB9CgkJfSBlbHNlIHsKCQkgICAgZGlyYyA9ICcgJzsKCQkgICAgaWYgKHNfbmFtZVswXSAhPSAwKSB7CgkJCWZpbGVzKys7CgkJCWRvaXQgPSAxOwoJCSAgICB9CgkJfQoJCWlmIChkb2l0KSB7CgkJICAgIGlmIChkaXJjID09ICcgJykgewoJCQlwcmludGYgKCIgJThsZCAgICVzJWNcbiIsCgkJCQkobG9uZykgRkFUMkNQVTMyIChkZW50cHRyLT5zaXplKSwgc19uYW1lLAoJCQkJZGlyYyk7CgkJICAgIH0gZWxzZSB7CgkJCXByaW50ZiAoIiAgICAgICAgICAgICVzJWNcbiIsIHNfbmFtZSwgZGlyYyk7CgkJICAgIH0KCQl9CgkJZGVudHB0cisrOwoJCWNvbnRpbnVlOwoJICAgIH0KCSAgICBpZiAoc3RyY21wKChjaGFyICopZm5hbWVjb3B5LCBzX25hbWUpICYmCgkJc3RyY21wKChjaGFyICopZm5hbWVjb3B5LCBsX25hbWUpKSB7CgkJRkFUX0RQUklOVCAoIlJvb3RNaXNtYXRjaDogfCVzfCVzfFxuIiwgc19uYW1lLCBsX25hbWUpOwoJCWRlbnRwdHIrKzsKCQljb250aW51ZTsKCSAgICB9CgkgICAgaWYgKGlzZGlyICYmICEoZGVudHB0ci0+YXR0ciAmIEFUVFJfRElSKSkKCQlyZXR1cm4gLTE7CgoJICAgIEZBVF9EUFJJTlQgKCJSb290TmFtZTogJXMiLCBzX25hbWUpOwoJICAgIEZBVF9EUFJJTlQgKCIsIHN0YXJ0OiAweCV4IiwgU1RBUlQgKGRlbnRwdHIpKTsKCSAgICBGQVRfRFBSSU5UICgiLCBzaXplOiAgMHgleCAlc1xuIiwKCQkJRkFUMkNQVTMyIChkZW50cHRyLT5zaXplKSwgaXNkaXIgPyAiKERJUikiIDogIiIpOwoKCSAgICBnb3RvIHJvb3RkaXJfZG9uZTsgIC8qIFdlIGdvdCBhIG1hdGNoICovCgl9CgljdXJzZWN0Kys7CiAgICB9CiAgcm9vdGRpcl9kb25lOgoKICAgIGZpcnN0dGltZSA9IDE7CiAgICB3aGlsZSAoaXNkaXIpIHsKCWludCBzdGFydHNlY3QgPSBteWRhdGEtPmRhdGFfYmVnaW4KCQkrIFNUQVJUIChkZW50cHRyKSAqIG15ZGF0YS0+Y2x1c3Rfc2l6ZTsKCWRpcl9lbnRyeSBkZW50OwoJY2hhciAqbmV4dG5hbWUgPSBOVUxMOwoKCWRlbnQgPSAqZGVudHB0cjsKCWRlbnRwdHIgPSAmZGVudDsKCWlkeCA9IGRpcmRlbGltIChzdWJuYW1lKTsKCWlmIChpZHggPj0gMCkgewoJICAgIHN1Ym5hbWVbaWR4XSA9ICdcMCc7CgkgICAgbmV4dG5hbWUgPSBzdWJuYW1lICsgaWR4ICsgMTsKCSAgICAvKiBIYW5kbGUgbXVsdGlwbGUgZGVsaW1pdGVycyAqLwoJICAgIHdoaWxlIChJU0RJUkRFTElNICgqbmV4dG5hbWUpKQoJCW5leHRuYW1lKys7CgkgICAgaWYgKGRvbHMgJiYgKm5leHRuYW1lID09ICdcMCcpCgkJZmlyc3R0aW1lID0gMDsKCX0gZWxzZSB7CgkgICAgaWYgKGRvbHMgJiYgZmlyc3R0aW1lKSB7CgkJZmlyc3R0aW1lID0gMDsKCSAgICB9IGVsc2UgewoJCWlzZGlyID0gMDsKCSAgICB9Cgl9CgoJaWYgKGdldF9kZW50ZnJvbWRpciAobXlkYXRhLCBzdGFydHNlY3QsIHN1Ym5hbWUsIGRlbnRwdHIsCgkJCSAgICAgaXNkaXIgPyAwIDogZG9scykgPT0gTlVMTCkgewoJICAgIGlmIChkb2xzICYmICFpc2RpcikKCQlyZXR1cm4gMDsKCSAgICByZXR1cm4gLTE7Cgl9CgoJaWYgKGlkeCA+PSAwKSB7CgkgICAgaWYgKCEoZGVudHB0ci0+YXR0ciAmIEFUVFJfRElSKSkKCQlyZXR1cm4gLTE7CgkgICAgc3VibmFtZSA9IG5leHRuYW1lOwoJfQogICAgfQogICAgcmV0ID0gZ2V0X2NvbnRlbnRzIChteWRhdGEsIGRlbnRwdHIsIGJ1ZmZlciwgbWF4c2l6ZSk7CiAgICBGQVRfRFBSSU5UICgiU2l6ZTogJWQsIGdvdDogJWxkXG4iLCBGQVQyQ1BVMzIgKGRlbnRwdHItPnNpemUpLCByZXQpOwoKICAgIHJldHVybiByZXQ7Cn0KCgppbnQKZmlsZV9mYXRfZGV0ZWN0ZnModm9pZCkKewoJYm9vdF9zZWN0b3IJYnM7Cgl2b2x1bWVfaW5mbwl2b2xpbmZvOwoJaW50CQlmYXRzaXplOwoJY2hhcgl2b2xfbGFiZWxbMTJdOwoKCWlmKGN1cl9kZXY9PU5VTEwpIHsKCQlwcmludGYoIk5vIGN1cnJlbnQgZGV2aWNlXG4iKTsKCQlyZXR1cm4gMTsKCX0KI2lmIChDT05GSUdfQ09NTUFORFMgJiBDRkdfQ01EX0lERSkgfHwgKENPTkZJR19DT01NQU5EUyAmIENGR19DTURfU0NTSSkgfHwgXAogICAgKENPTkZJR19DT01NQU5EUyAmIENGR19DTURfVVNCKSB8fCAoQ09ORklHX01NQykKCXByaW50ZigiSW50ZXJmYWNlOiAgIik7Cglzd2l0Y2goY3VyX2Rldi0+aWZfdHlwZSkgewoJCWNhc2UgSUZfVFlQRV9JREUgOglwcmludGYoIklERSIpOyBicmVhazsKCQljYXNlIElGX1RZUEVfU0NTSSA6CXByaW50ZigiU0NTSSIpOyBicmVhazsKCQljYXNlIElGX1RZUEVfQVRBUEkgOglwcmludGYoIkFUQVBJIik7IGJyZWFrOwoJCWNhc2UgSUZfVFlQRV9VU0IgOglwcmludGYoIlVTQiIpOyBicmVhazsKCQljYXNlIElGX1RZUEVfRE9DIDoJcHJpbnRmKCJET0MiKTsgYnJlYWs7CgkJY2FzZSBJRl9UWVBFX01NQyA6CXByaW50ZigiTU1DIik7IGJyZWFrOwoJCWRlZmF1bHQgOgkJcHJpbnRmKCJVbmtub3duIik7Cgl9CglwcmludGYoIlxuICBEZXZpY2UgJWQ6ICIsY3VyX2Rldi0+ZGV2KTsKCWRldl9wcmludChjdXJfZGV2KTsKI2VuZGlmCglpZihyZWFkX2Jvb3RzZWN0YW5kdmkoJmJzLCAmdm9saW5mbywgJmZhdHNpemUpKSB7CgkJcHJpbnRmKCJcbk5vIHZhbGlkIEZBVCBmcyBmb3VuZFxuIik7CgkJcmV0dXJuIDE7Cgl9CgltZW1jcHkgKHZvbF9sYWJlbCwgdm9saW5mby52b2x1bWVfbGFiZWwsIDExKTsKCXZvbF9sYWJlbFsxMV0gPSAnXDAnOwoJdm9saW5mby5mc190eXBlWzVdPSdcMCc7CglwcmludGYoIlBhcnRpdGlvbiAlZDogRmlsZXN5c3RlbTogJXMgXCIlc1wiXG4iLGN1cl9wYXJ0LHZvbGluZm8uZnNfdHlwZSx2b2xfbGFiZWwpOwoJcmV0dXJuIDA7Cn0KCgppbnQKZmlsZV9mYXRfbHMoY29uc3QgY2hhciAqZGlyKQp7CglyZXR1cm4gZG9fZmF0X3JlYWQoZGlyLCBOVUxMLCAwLCBMU19ZRVMpOwp9CgoKbG9uZwpmaWxlX2ZhdF9yZWFkKGNvbnN0IGNoYXIgKmZpbGVuYW1lLCB2b2lkICpidWZmZXIsIHVuc2lnbmVkIGxvbmcgbWF4c2l6ZSkKewoJbG9uZyByZXQ7CglyZXQgPSBkb19mYXRfcmVhZChmaWxlbmFtZSwgYnVmZmVyLCBtYXhzaXplLCBMU19OTyk7CglyZXR1cm4gcmV0Owp9CgojZW5kaWYgLyogI2lmIChDT05GSUdfQ09NTUFORFMgJiBDRkdfQ01EX0ZBVCkgKi8K