LyoKICogZmF0LmMKICoKICogUi9PIChWKUZBVCAxMi8xNi8zMiBmaWxlc3lzdGVtIGltcGxlbWVudGF0aW9uIGJ5IE1hcmN1cyBTdW5kYmVyZwogKgogKiAyMDAyLTA3LTI4IC0gcmpvbmVzQG5leHVzLXRlY2gubmV0IC0gcG9ydGVkIHRvIHBwY2Jvb3QgdjEuMS42CiAqIDIwMDMtMDMtMTAgLSBraGFycmlzQG5leHVzLXRlY2gubmV0IC0gcG9ydGVkIHRvIHVib290CiAqCiAqIFNlZSBmaWxlIENSRURJVFMgZm9yIGxpc3Qgb2YgcGVvcGxlIHdobyBjb250cmlidXRlZCB0byB0aGlzCiAqIHByb2plY3QuCiAqCiAqIFRoaXMgcHJvZ3JhbSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IKICogbW9kaWZ5IGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgYXMKICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlciB2ZXJzaW9uIDIgb2YKICogdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uCiAqCiAqIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLAogKiBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZgogKiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlCiAqIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCiAqIGFsb25nIHdpdGggdGhpcyBwcm9ncmFtOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlCiAqIEZvdW5kYXRpb24sIEluYy4sIDU5IFRlbXBsZSBQbGFjZSwgU3VpdGUgMzMwLCBCb3N0b24sCiAqIE1BIDAyMTExLTEzMDcgVVNBCiAqLwoKI2luY2x1ZGUgPGNvbW1vbi5oPgojaW5jbHVkZSA8Y29uZmlnLmg+CiNpbmNsdWRlIDxmYXQuaD4KI2luY2x1ZGUgPGFzbS9ieXRlb3JkZXIuaD4KI2luY2x1ZGUgPHBhcnQuaD4KCiNpZiAoQ09ORklHX0NPTU1BTkRTICYgQ0ZHX0NNRF9GQVQpCgovKgogKiBDb252ZXJ0IGEgc3RyaW5nIHRvIGxvd2VyY2FzZS4KICovCnN0YXRpYyB2b2lkCmRvd25jYXNlKGNoYXIgKnN0cikKewoJd2hpbGUgKCpzdHIgIT0gJ1wwJykgewoJCVRPTE9XRVIoKnN0cik7CgkJc3RyKys7Cgl9Cn0KCnN0YXRpYyAgYmxvY2tfZGV2X2Rlc2NfdCAqY3VyX2RldiA9IE5VTEw7CnN0YXRpYyB1bnNpZ25lZCBsb25nIHBhcnRfb2Zmc2V0ID0gMDsKc3RhdGljIGludCBjdXJfcGFydCA9IDE7CgojZGVmaW5lIERPU19QQVJUX1RCTF9PRkZTRVQJMHgxYmUKI2RlZmluZSBET1NfUEFSVF9NQUdJQ19PRkZTRVQJMHgxZmUKI2RlZmluZSBET1NfRlNfVFlQRV9PRkZTRVQJMHgzNgoKaW50IGRpc2tfcmVhZCAoX191MzIgc3RhcnRibG9jaywgX191MzIgZ2V0c2l6ZSwgX191OCAqIGJ1ZnB0cikKewoJc3RhcnRibG9jayArPSBwYXJ0X29mZnNldDsKCWlmIChjdXJfZGV2ID09IE5VTEwpCgkJcmV0dXJuIC0xOwoJaWYgKGN1cl9kZXYtPmJsb2NrX3JlYWQpIHsKCQlyZXR1cm4gY3VyX2Rldi0+YmxvY2tfcmVhZCAoY3VyX2Rldi0+ZGV2LCBzdGFydGJsb2NrLCBnZXRzaXplLCAodW5zaWduZWQgbG9uZyAqKWJ1ZnB0cik7Cgl9CglyZXR1cm4gLTE7Cn0KCgppbnQKZmF0X3JlZ2lzdGVyX2RldmljZShibG9ja19kZXZfZGVzY190ICpkZXZfZGVzYywgaW50IHBhcnRfbm8pCnsKCXVuc2lnbmVkIGNoYXIgYnVmZmVyW1NFQ1RPUl9TSVpFXTsKCglpZiAoIWRldl9kZXNjLT5ibG9ja19yZWFkKQoJCXJldHVybiAtMTsKCWN1cl9kZXY9ZGV2X2Rlc2M7CgkvKiBjaGVjayBpZiB3ZSBoYXZlIGEgTUJSIChvbiBmbG9wcGllcyB3ZSBoYXZlIG9ubHkgYSBQQlIpICovCglpZiAoZGV2X2Rlc2MtPmJsb2NrX3JlYWQgKGRldl9kZXNjLT5kZXYsIDAsIDEsICh1bG9uZyAqKSBidWZmZXIpICE9IDEpIHsKCQlwcmludGYgKCIqKiBDYW4ndCByZWFkIGZyb20gZGV2aWNlICVkICoqXG4iLCBkZXZfZGVzYy0+ZGV2KTsKCQlyZXR1cm4gLTE7Cgl9CglpZiAoYnVmZmVyW0RPU19QQVJUX01BR0lDX09GRlNFVF0gIT0gMHg1NSB8fAoJCWJ1ZmZlcltET1NfUEFSVF9NQUdJQ19PRkZTRVQgKyAxXSAhPSAweGFhKSB7CgkJLyogbm8gc2lnbmF0dXJlIGZvdW5kICovCgkJcmV0dXJuIC0xOwoJfQoJaWYoIXN0cm5jbXAoKGNoYXIgKikmYnVmZmVyW0RPU19GU19UWVBFX09GRlNFVF0sIkZBVCIsMykpIHsKCQkvKiBvaywgd2UgYXNzdW1lIHdlIGFyZSBvbiBhIFBCUiBvbmx5ICovCgkJY3VyX3BhcnQgPSAxOwoJCXBhcnRfb2Zmc2V0PTA7Cgl9CgllbHNlIHsKI2lmIChDT05GSUdfQ09NTUFORFMgJiBDRkdfQ01EX0lERSkgfHwgKENPTkZJR19DT01NQU5EUyAmIENGR19DTURfU0NTSSkgfHwgXAogICAgKENPTkZJR19DT01NQU5EUyAmIENGR19DTURfVVNCKSB8fCBkZWZpbmVkKENPTkZJR19TWVNURU1BQ0UpCgkJZGlza19wYXJ0aXRpb25fdCBpbmZvOwoJCWlmKCFnZXRfcGFydGl0aW9uX2luZm8oZGV2X2Rlc2MsIHBhcnRfbm8sICZpbmZvKSkgewoJCQlwYXJ0X29mZnNldCA9IGluZm8uc3RhcnQ7CgkJCWN1cl9wYXJ0ID0gcGFydF9ubzsKCQl9CgkJZWxzZSB7CgkJCXByaW50ZiAoIioqIFBhcnRpdGlvbiAlZCBub3QgdmFsaWQgb24gZGV2aWNlICVkICoqXG4iLHBhcnRfbm8sZGV2X2Rlc2MtPmRldik7CgkJCXJldHVybiAtMTsKCQl9CiNlbHNlCgkJLyogRklYTUUgd2UgbmVlZCB0byBkZXRlcm1pbmUgdGhlIHN0YXJ0IGJsb2NrIG9mIHRoZQoJCSAqIHBhcnRpdGlvbiB3aGVyZSB0aGUgRE9TIEZTIHJlc2lkZXMuIFRoaXMgY2FuIGJlIGRvbmUKCQkgKiBieSB1c2luZyB0aGUgZ2V0X3BhcnRpdGlvbl9pbmZvIHJvdXRpbmUuIEZvciB0aGlzCgkJICogcHVycG9zZSB0aGUgbGlicGFydCBtdXN0IGJlIGluY2x1ZGVkLgoJCSAqLwoJCXBhcnRfb2Zmc2V0PTMyOwoJCWN1cl9wYXJ0ID0gMTsKI2VuZGlmCgl9CglyZXR1cm4gMDsKfQoKCi8qCiAqIEdldCB0aGUgZmlyc3Qgb2NjdXJlbmNlIG9mIGEgZGlyZWN0b3J5IGRlbGltaXRlciAoJy8nIG9yICdcJykgaW4gYSBzdHJpbmcuCiAqIFJldHVybiBpbmRleCBpbnRvIHN0cmluZyBpZiBmb3VuZCwgLTEgb3RoZXJ3aXNlLgogKi8Kc3RhdGljIGludApkaXJkZWxpbShjaGFyICpzdHIpCnsKCWNoYXIgKnN0YXJ0ID0gc3RyOwoKCXdoaWxlICgqc3RyICE9ICdcMCcpIHsKCQlpZiAoSVNESVJERUxJTSgqc3RyKSkgcmV0dXJuIHN0ciAtIHN0YXJ0OwoJCXN0cisrOwoJfQoJcmV0dXJuIC0xOwp9CgoKLyoKICogTWF0Y2ggdm9sdW1lX2luZm8gZnNfdHlwZSBzdHJpbmdzLgogKiBSZXR1cm4gMCBvbiBtYXRjaCwgLTEgb3RoZXJ3aXNlLgogKi8Kc3RhdGljIGludApjb21wYXJlX3NpZ24oY2hhciAqc3RyMSwgY2hhciAqc3RyMikKewoJY2hhciAqZW5kID0gc3RyMStTSUdOTEVOOwoKCXdoaWxlIChzdHIxICE9IGVuZCkgewoJCWlmICgqc3RyMSAhPSAqc3RyMikgewoJCQlyZXR1cm4gLTE7CgkJfQoJCXN0cjErKzsKCQlzdHIyKys7Cgl9CgoJcmV0dXJuIDA7Cn0KCgovKgogKiBFeHRyYWN0IHplcm8gdGVybWluYXRlZCBzaG9ydCBuYW1lIGZyb20gYSBkaXJlY3RvcnkgZW50cnkuCiAqLwpzdGF0aWMgdm9pZCBnZXRfbmFtZSAoZGlyX2VudHJ5ICpkaXJlbnQsIGNoYXIgKnNfbmFtZSkKewoJY2hhciAqcHRyOwoKCW1lbWNweSAoc19uYW1lLCBkaXJlbnQtPm5hbWUsIDgpOwoJc19uYW1lWzhdID0gJ1wwJzsKCXB0ciA9IHNfbmFtZTsKCXdoaWxlICgqcHRyICYmICpwdHIgIT0gJyAnKQoJCXB0cisrOwoJaWYgKGRpcmVudC0+ZXh0WzBdICYmIGRpcmVudC0+ZXh0WzBdICE9ICcgJykgewoJCSpwdHIgPSAnLic7CgkJcHRyKys7CgkJbWVtY3B5IChwdHIsIGRpcmVudC0+ZXh0LCAzKTsKCQlwdHJbM10gPSAnXDAnOwoJCXdoaWxlICgqcHRyICYmICpwdHIgIT0gJyAnKQoJCQlwdHIrKzsKCX0KCSpwdHIgPSAnXDAnOwoJaWYgKCpzX25hbWUgPT0gREVMRVRFRF9GTEFHKQoJCSpzX25hbWUgPSAnXDAnOwoJZWxzZSBpZiAoKnNfbmFtZSA9PSBhUklORykKCQkqc19uYW1lID0gJ+UnOwoJZG93bmNhc2UgKHNfbmFtZSk7Cn0KCi8qCiAqIEdldCB0aGUgZW50cnkgYXQgaW5kZXggJ2VudHJ5JyBpbiBhIEZBVCAoMTIvMTYvMzIpIHRhYmxlLgogKiBPbiBmYWlsdXJlIDB4MDAgaXMgcmV0dXJuZWQuCiAqLwpzdGF0aWMgX191MzIKZ2V0X2ZhdGVudChmc2RhdGEgKm15ZGF0YSwgX191MzIgZW50cnkpCnsKCV9fdTMyIGJ1Zm51bTsKCV9fdTMyIG9mZnNldDsKCV9fdTMyIHJldCA9IDB4MDA7CgoJc3dpdGNoIChteWRhdGEtPmZhdHNpemUpIHsKCWNhc2UgMzI6CgkJYnVmbnVtID0gZW50cnkgLyBGQVQzMkJVRlNJWkU7CgkJb2Zmc2V0ID0gZW50cnkgLSBidWZudW0gKiBGQVQzMkJVRlNJWkU7CgkJYnJlYWs7CgljYXNlIDE2OgoJCWJ1Zm51bSA9IGVudHJ5IC8gRkFUMTZCVUZTSVpFOwoJCW9mZnNldCA9IGVudHJ5IC0gYnVmbnVtICogRkFUMTZCVUZTSVpFOwoJCWJyZWFrOwoJY2FzZSAxMjoKCQlidWZudW0gPSBlbnRyeSAvIEZBVDEyQlVGU0laRTsKCQlvZmZzZXQgPSBlbnRyeSAtIGJ1Zm51bSAqIEZBVDEyQlVGU0laRTsKCQlicmVhazsKCglkZWZhdWx0OgoJCS8qIFVuc3VwcG9ydGVkIEZBVCBzaXplICovCgkJcmV0dXJuIHJldDsKCX0KCgkvKiBSZWFkIGEgbmV3IGJsb2NrIG9mIEZBVCBlbnRyaWVzIGludG8gdGhlIGNhY2hlLiAqLwoJaWYgKGJ1Zm51bSAhPSBteWRhdGEtPmZhdGJ1Zm51bSkgewoJCWludCBnZXRzaXplID0gRkFUQlVGU0laRS9GU19CTE9DS19TSVpFOwoJCV9fdTggKmJ1ZnB0ciA9IG15ZGF0YS0+ZmF0YnVmOwoJCV9fdTMyIGZhdGxlbmd0aCA9IG15ZGF0YS0+ZmF0bGVuZ3RoOwoJCV9fdTMyIHN0YXJ0YmxvY2sgPSBidWZudW0gKiBGQVRCVUZCTE9DS1M7CgoJCWZhdGxlbmd0aCAqPSBTRUNUT1JfU0laRTsJLyogV2Ugd2FudCBpdCBpbiBieXRlcyBub3cgKi8KCQlzdGFydGJsb2NrICs9IG15ZGF0YS0+ZmF0X3NlY3Q7CS8qIE9mZnNldCBmcm9tIHN0YXJ0IG9mIGRpc2sgKi8KCgkJaWYgKGdldHNpemUgPiBmYXRsZW5ndGgpIGdldHNpemUgPSBmYXRsZW5ndGg7CgkJaWYgKGRpc2tfcmVhZChzdGFydGJsb2NrLCBnZXRzaXplLCBidWZwdHIpIDwgMCkgewoJCQlGQVRfRFBSSU5UKCJFcnJvciByZWFkaW5nIEZBVCBibG9ja3NcbiIpOwoJCQlyZXR1cm4gcmV0OwoJCX0KCQlteWRhdGEtPmZhdGJ1Zm51bSA9IGJ1Zm51bTsKCX0KCgkvKiBHZXQgdGhlIGFjdHVhbCBlbnRyeSBmcm9tIHRoZSB0YWJsZSAqLwoJc3dpdGNoIChteWRhdGEtPmZhdHNpemUpIHsKCWNhc2UgMzI6CgkJcmV0ID0gRkFUMkNQVTMyKCgoX191MzIqKW15ZGF0YS0+ZmF0YnVmKVtvZmZzZXRdKTsKCQlicmVhazsKCWNhc2UgMTY6CgkJcmV0ID0gRkFUMkNQVTE2KCgoX191MTYqKW15ZGF0YS0+ZmF0YnVmKVtvZmZzZXRdKTsKCQlicmVhazsKCWNhc2UgMTI6IHsKCQlfX3UzMiBvZmYxNiA9IChvZmZzZXQqMykvNDsKCQlfX3UxNiB2YWwxLCB2YWwyOwoKCQlzd2l0Y2ggKG9mZnNldCAmIDB4MykgewoJCWNhc2UgMDoKCQkJcmV0ID0gRkFUMkNQVTE2KCgoX191MTYqKW15ZGF0YS0+ZmF0YnVmKVtvZmYxNl0pOwoJCQlyZXQgJj0gMHhmZmY7CgkJCWJyZWFrOwoJCWNhc2UgMToKCQkJdmFsMSA9IEZBVDJDUFUxNigoKF9fdTE2KilteWRhdGEtPmZhdGJ1Zilbb2ZmMTZdKTsKCQkJdmFsMSAmPSAweGYwMDA7CgkJCXZhbDIgPSBGQVQyQ1BVMTYoKChfX3UxNiopbXlkYXRhLT5mYXRidWYpW29mZjE2KzFdKTsKCQkJdmFsMiAmPSAweDAwZmY7CgkJCXJldCA9ICh2YWwyIDw8IDQpIHwgKHZhbDEgPj4gMTIpOwoJCQlicmVhazsKCQljYXNlIDI6CgkJCXZhbDEgPSBGQVQyQ1BVMTYoKChfX3UxNiopbXlkYXRhLT5mYXRidWYpW29mZjE2XSk7CgkJCXZhbDEgJj0gMHhmZjAwOwoJCQl2YWwyID0gRkFUMkNQVTE2KCgoX191MTYqKW15ZGF0YS0+ZmF0YnVmKVtvZmYxNisxXSk7CgkJCXZhbDIgJj0gMHgwMDBmOwoJCQlyZXQgPSAodmFsMiA8PCA4KSB8ICh2YWwxID4+IDgpOwoJCQlicmVhazsKCQljYXNlIDM6CgkJCXJldCA9IEZBVDJDUFUxNigoKF9fdTE2KilteWRhdGEtPmZhdGJ1Zilbb2ZmMTZdKTs7CgkJCXJldCA9IChyZXQgJiAweGZmZjApID4+IDQ7CgkJCWJyZWFrOwoJCWRlZmF1bHQ6CgkJCWJyZWFrOwoJCX0KCX0KCWJyZWFrOwoJfQoJRkFUX0RQUklOVCgicmV0OiAlZCwgb2Zmc2V0OiAlZFxuIiwgcmV0LCBvZmZzZXQpOwoKCXJldHVybiByZXQ7Cn0KCgovKgogKiBSZWFkIGF0IG1vc3QgJ3NpemUnIGJ5dGVzIGZyb20gdGhlIHNwZWNpZmllZCBjbHVzdGVyIGludG8gJ2J1ZmZlcicuCiAqIFJldHVybiAwIG9uIHN1Y2Nlc3MsIC0xIG90aGVyd2lzZS4KICovCnN0YXRpYyBpbnQKZ2V0X2NsdXN0ZXIoZnNkYXRhICpteWRhdGEsIF9fdTMyIGNsdXN0bnVtLCBfX3U4ICpidWZmZXIsIHVuc2lnbmVkIGxvbmcgc2l6ZSkKewoJaW50IGlkeCA9IDA7CglfX3UzMiBzdGFydHNlY3Q7CgoJaWYgKGNsdXN0bnVtID4gMCkgewoJCXN0YXJ0c2VjdCA9IG15ZGF0YS0+ZGF0YV9iZWdpbiArIGNsdXN0bnVtKm15ZGF0YS0+Y2x1c3Rfc2l6ZTsKCX0gZWxzZSB7CgkJc3RhcnRzZWN0ID0gbXlkYXRhLT5yb290ZGlyX3NlY3Q7Cgl9CgoJRkFUX0RQUklOVCgiZ2MgLSBjbHVzdG51bTogJWQsIHN0YXJ0c2VjdDogJWRcbiIsIGNsdXN0bnVtLCBzdGFydHNlY3QpOwoJaWYgKGRpc2tfcmVhZChzdGFydHNlY3QsIHNpemUvRlNfQkxPQ0tfU0laRSAsIGJ1ZmZlcikgPCAwKSB7CgkJRkFUX0RQUklOVCgiRXJyb3IgcmVhZGluZyBkYXRhXG4iKTsKCQlyZXR1cm4gLTE7Cgl9CglpZihzaXplICUgRlNfQkxPQ0tfU0laRSkgewoJCV9fdTggdG1wYnVmW0ZTX0JMT0NLX1NJWkVdOwoJCWlkeD0gc2l6ZS9GU19CTE9DS19TSVpFOwoJCWlmIChkaXNrX3JlYWQoc3RhcnRzZWN0ICsgaWR4LCAxLCB0bXBidWYpIDwgMCkgewoJCQlGQVRfRFBSSU5UKCJFcnJvciByZWFkaW5nIGRhdGFcbiIpOwoJCQlyZXR1cm4gLTE7CgkJfQoJCWJ1ZmZlciArPSBpZHgqRlNfQkxPQ0tfU0laRTsKCgkJbWVtY3B5KGJ1ZmZlciwgdG1wYnVmLCBzaXplICUgRlNfQkxPQ0tfU0laRSk7CgkJcmV0dXJuIDA7Cgl9CgoJcmV0dXJuIDA7Cn0KCgovKgogKiBSZWFkIGF0IG1vc3QgJ21heHNpemUnIGJ5dGVzIGZyb20gdGhlIGZpbGUgYXNzb2NpYXRlZCB3aXRoICdkZW50cHRyJwogKiBpbnRvICdidWZmZXInLgogKiBSZXR1cm4gdGhlIG51bWJlciBvZiBieXRlcyByZWFkIG9yIC0xIG9uIGZhdGFsIGVycm9ycy4KICovCnN0YXRpYyBsb25nCmdldF9jb250ZW50cyhmc2RhdGEgKm15ZGF0YSwgZGlyX2VudHJ5ICpkZW50cHRyLCBfX3U4ICpidWZmZXIsCgkgICAgIHVuc2lnbmVkIGxvbmcgbWF4c2l6ZSkKewoJdW5zaWduZWQgbG9uZyBmaWxlc2l6ZSA9IEZBVDJDUFUzMihkZW50cHRyLT5zaXplKSwgZ290c2l6ZSA9IDA7Cgl1bnNpZ25lZCBpbnQgYnl0ZXNwZXJjbHVzdCA9IG15ZGF0YS0+Y2x1c3Rfc2l6ZSAqIFNFQ1RPUl9TSVpFOwoJX191MzIgY3VyY2x1c3QgPSBTVEFSVChkZW50cHRyKTsKCV9fdTMyIGVuZGNsdXN0LCBuZXdjbHVzdDsKCXVuc2lnbmVkIGxvbmcgYWN0c2l6ZTsKCglGQVRfRFBSSU5UKCJGaWxlc2l6ZTogJWxkIGJ5dGVzXG4iLCBmaWxlc2l6ZSk7CgoJaWYgKG1heHNpemUgPiAwICYmIGZpbGVzaXplID4gbWF4c2l6ZSkgZmlsZXNpemUgPSBtYXhzaXplOwoKCUZBVF9EUFJJTlQoIlJlYWRpbmc6ICVsZCBieXRlc1xuIiwgZmlsZXNpemUpOwoKCWFjdHNpemU9Ynl0ZXNwZXJjbHVzdDsKCWVuZGNsdXN0PWN1cmNsdXN0OwoJZG8gewoJCS8qIHNlYXJjaCBmb3IgY29uc2VjdXRpdmUgY2x1c3RlcnMgKi8KCQl3aGlsZShhY3RzaXplIDwgZmlsZXNpemUpIHsKCQkJbmV3Y2x1c3QgPSBnZXRfZmF0ZW50KG15ZGF0YSwgZW5kY2x1c3QpOwoJCQlpZigobmV3Y2x1c3QgLTEpIT1lbmRjbHVzdCkKCQkJCWdvdG8gZ2V0aXQ7CgkJCWlmIChuZXdjbHVzdCA8PSAweDAwMDEgfHwgbmV3Y2x1c3QgPj0gMHhmZmYwKSB7CgkJCQlGQVRfRFBSSU5UKCJjdXJjbHVzdDogMHgleFxuIiwgbmV3Y2x1c3QpOwoJCQkJRkFUX0RQUklOVCgiSW52YWxpZCBGQVQgZW50cnlcbiIpOwoJCQkJcmV0dXJuIGdvdHNpemU7CgkJCX0KCQkJZW5kY2x1c3Q9bmV3Y2x1c3Q7CgkJCWFjdHNpemUrPSBieXRlc3BlcmNsdXN0OwoJCX0KCQkvKiBhY3RzaXplID49IGZpbGUgc2l6ZSAqLwoJCWFjdHNpemUgLT0gYnl0ZXNwZXJjbHVzdDsKCQkvKiBnZXQgcmVtYWluaW5nIGNsdXN0ZXJzICovCgkJaWYgKGdldF9jbHVzdGVyKG15ZGF0YSwgY3VyY2x1c3QsIGJ1ZmZlciwgKGludClhY3RzaXplKSAhPSAwKSB7CgkJCUZBVF9FUlJPUigiRXJyb3IgcmVhZGluZyBjbHVzdGVyXG4iKTsKCQkJcmV0dXJuIC0xOwoJCX0KCQkvKiBnZXQgcmVtYWluaW5nIGJ5dGVzICovCgkJZ290c2l6ZSArPSAoaW50KWFjdHNpemU7CgkJZmlsZXNpemUgLT0gYWN0c2l6ZTsKCQlidWZmZXIgKz0gYWN0c2l6ZTsKCQlhY3RzaXplPSBmaWxlc2l6ZTsKCQlpZiAoZ2V0X2NsdXN0ZXIobXlkYXRhLCBlbmRjbHVzdCwgYnVmZmVyLCAoaW50KWFjdHNpemUpICE9IDApIHsKCQkJRkFUX0VSUk9SKCJFcnJvciByZWFkaW5nIGNsdXN0ZXJcbiIpOwoJCQlyZXR1cm4gLTE7CgkJfQoJCWdvdHNpemUrPWFjdHNpemU7CgkJcmV0dXJuIGdvdHNpemU7CmdldGl0OgoJCWlmIChnZXRfY2x1c3RlcihteWRhdGEsIGN1cmNsdXN0LCBidWZmZXIsIChpbnQpYWN0c2l6ZSkgIT0gMCkgewoJCQlGQVRfRVJST1IoIkVycm9yIHJlYWRpbmcgY2x1c3RlclxuIik7CgkJCXJldHVybiAtMTsKCQl9CgkJZ290c2l6ZSArPSAoaW50KWFjdHNpemU7CgkJZmlsZXNpemUgLT0gYWN0c2l6ZTsKCQlidWZmZXIgKz0gYWN0c2l6ZTsKCQljdXJjbHVzdCA9IGdldF9mYXRlbnQobXlkYXRhLCBlbmRjbHVzdCk7CgkJaWYgKGN1cmNsdXN0IDw9IDB4MDAwMSB8fCBjdXJjbHVzdCA+PSAweGZmZjApIHsKCQkJRkFUX0RQUklOVCgiY3VyY2x1c3Q6IDB4JXhcbiIsIGN1cmNsdXN0KTsKCQkJRkFUX0VSUk9SKCJJbnZhbGlkIEZBVCBlbnRyeVxuIik7CgkJCXJldHVybiBnb3RzaXplOwoJCX0KCQlhY3RzaXplPWJ5dGVzcGVyY2x1c3Q7CgkJZW5kY2x1c3Q9Y3VyY2x1c3Q7Cgl9IHdoaWxlICgxKTsKfQoKCiNpZmRlZiBDT05GSUdfU1VQUE9SVF9WRkFUCi8qCiAqIEV4dHJhY3QgdGhlIGZpbGUgbmFtZSBpbmZvcm1hdGlvbiBmcm9tICdzbG90cHRyJyBpbnRvICdsX25hbWUnLAogKiBzdGFydGluZyBhdCBsX25hbWVbKmlkeF0uCiAqIFJldHVybiAxIGlmIHRlcm1pbmF0b3IgKHplcm8gYnl0ZSkgaXMgZm91bmQsIDAgb3RoZXJ3aXNlLgogKi8Kc3RhdGljIGludApzbG90MnN0cihkaXJfc2xvdCAqc2xvdHB0ciwgY2hhciAqbF9uYW1lLCBpbnQgKmlkeCkKewoJaW50IGo7CgoJZm9yIChqID0gMDsgaiA8PSA4OyBqICs9IDIpIHsKCQlsX25hbWVbKmlkeF0gPSBzbG90cHRyLT5uYW1lMF80W2pdOwoJCWlmIChsX25hbWVbKmlkeF0gPT0gMHgwMCkgcmV0dXJuIDE7CgkJKCppZHgpKys7Cgl9Cglmb3IgKGogPSAwOyBqIDw9IDEwOyBqICs9IDIpIHsKCQlsX25hbWVbKmlkeF0gPSBzbG90cHRyLT5uYW1lNV8xMFtqXTsKCQlpZiAobF9uYW1lWyppZHhdID09IDB4MDApIHJldHVybiAxOwoJCSgqaWR4KSsrOwoJfQoJZm9yIChqID0gMDsgaiA8PSAyOyBqICs9IDIpIHsKCQlsX25hbWVbKmlkeF0gPSBzbG90cHRyLT5uYW1lMTFfMTJbal07CgkJaWYgKGxfbmFtZVsqaWR4XSA9PSAweDAwKSByZXR1cm4gMTsKCQkoKmlkeCkrKzsKCX0KCglyZXR1cm4gMDsKfQoKCi8qCiAqIEV4dHJhY3QgdGhlIGZ1bGwgbG9uZyBmaWxlbmFtZSBzdGFydGluZyBhdCAncmV0ZGVudCcgKHdoaWNoIGlzIHJlYWxseQogKiBhIHNsb3QpIGludG8gJ2xfbmFtZScuIElmIHN1Y2Nlc3NmdWwgYWxzbyBjb3B5IHRoZSByZWFsIGRpcmVjdG9yeSBlbnRyeQogKiBpbnRvICdyZXRkZW50JwogKiBSZXR1cm4gMCBvbiBzdWNjZXNzLCAtMSBvdGhlcndpc2UuCiAqLwpfX3U4CSBnZXRfdmZhdG5hbWVfYmxvY2tbTUFYX0NMVVNUU0laRV07CnN0YXRpYyBpbnQKZ2V0X3ZmYXRuYW1lKGZzZGF0YSAqbXlkYXRhLCBpbnQgY3VyY2x1c3QsIF9fdTggKmNsdXN0ZXIsCgkgICAgIGRpcl9lbnRyeSAqcmV0ZGVudCwgY2hhciAqbF9uYW1lKQp7CglkaXJfZW50cnkgKnJlYWxkZW50OwoJZGlyX3Nsb3QgICpzbG90cHRyID0gKGRpcl9zbG90KikgcmV0ZGVudDsKCV9fdTgJICAqbmV4dGNsdXN0ID0gY2x1c3RlciArIG15ZGF0YS0+Y2x1c3Rfc2l6ZSAqIFNFQ1RPUl9TSVpFOwoJX191OAkgICBjb3VudGVyID0gKHNsb3RwdHItPmlkICYgfkxBU1RfTE9OR19FTlRSWV9NQVNLKSAmIDB4ZmY7CglpbnQgaWR4ID0gMDsKCgl3aGlsZSAoKF9fdTgqKXNsb3RwdHIgPCBuZXh0Y2x1c3QpIHsKCQlpZiAoY291bnRlciA9PSAwKSBicmVhazsKCQlpZiAoKChzbG90cHRyLT5pZCAmIH5MQVNUX0xPTkdfRU5UUllfTUFTSykgJiAweGZmKSAhPSBjb3VudGVyKQoJCQlyZXR1cm4gLTE7CgkJc2xvdHB0cisrOwoJCWNvdW50ZXItLTsKCX0KCglpZiAoKF9fdTgqKXNsb3RwdHIgPj0gbmV4dGNsdXN0KSB7CgkJZGlyX3Nsb3QgKnNsb3RwdHIyOwoKCQlzbG90cHRyLS07CgkJY3VyY2x1c3QgPSBnZXRfZmF0ZW50KG15ZGF0YSwgY3VyY2x1c3QpOwoJCWlmIChjdXJjbHVzdCA8PSAweDAwMDEgfHwgY3VyY2x1c3QgPj0gMHhmZmYwKSB7CgkJCUZBVF9EUFJJTlQoImN1cmNsdXN0OiAweCV4XG4iLCBjdXJjbHVzdCk7CgkJCUZBVF9FUlJPUigiSW52YWxpZCBGQVQgZW50cnlcbiIpOwoJCQlyZXR1cm4gLTE7CgkJfQoJCWlmIChnZXRfY2x1c3RlcihteWRhdGEsIGN1cmNsdXN0LCBnZXRfdmZhdG5hbWVfYmxvY2ssCgkJCQlteWRhdGEtPmNsdXN0X3NpemUgKiBTRUNUT1JfU0laRSkgIT0gMCkgewoJCQlGQVRfRFBSSU5UKCJFcnJvcjogcmVhZGluZyBkaXJlY3RvcnkgYmxvY2tcbiIpOwoJCQlyZXR1cm4gLTE7CgkJfQoJCXNsb3RwdHIyID0gKGRpcl9zbG90KikgZ2V0X3ZmYXRuYW1lX2Jsb2NrOwoJCXdoaWxlIChzbG90cHRyMi0+aWQgPiAweDAxKSB7CgkJCXNsb3RwdHIyKys7CgkJfQoJCS8qIFNhdmUgdGhlIHJlYWwgZGlyZWN0b3J5IGVudHJ5ICovCgkJcmVhbGRlbnQgPSAoZGlyX2VudHJ5KilzbG90cHRyMiArIDE7CgkJd2hpbGUgKChfX3U4KilzbG90cHRyMiA+PSBnZXRfdmZhdG5hbWVfYmxvY2spIHsKCQkJc2xvdDJzdHIoc2xvdHB0cjIsIGxfbmFtZSwgJmlkeCk7CgkJCXNsb3RwdHIyLS07CgkJfQoJfSBlbHNlIHsKCQkvKiBTYXZlIHRoZSByZWFsIGRpcmVjdG9yeSBlbnRyeSAqLwoJCXJlYWxkZW50ID0gKGRpcl9lbnRyeSopc2xvdHB0cjsKCX0KCglkbyB7CgkJc2xvdHB0ci0tOwoJCWlmIChzbG90MnN0cihzbG90cHRyLCBsX25hbWUsICZpZHgpKSBicmVhazsKCX0gd2hpbGUgKCEoc2xvdHB0ci0+aWQgJiBMQVNUX0xPTkdfRU5UUllfTUFTSykpOwoKCWxfbmFtZVtpZHhdID0gJ1wwJzsKCWlmICgqbF9uYW1lID09IERFTEVURURfRkxBRykgKmxfbmFtZSA9ICdcMCc7CgllbHNlIGlmICgqbF9uYW1lID09IGFSSU5HKSAqbF9uYW1lID0gJ+UnOwoJZG93bmNhc2UobF9uYW1lKTsKCgkvKiBSZXR1cm4gdGhlIHJlYWwgZGlyZWN0b3J5IGVudHJ5ICovCgltZW1jcHkocmV0ZGVudCwgcmVhbGRlbnQsIHNpemVvZihkaXJfZW50cnkpKTsKCglyZXR1cm4gMDsKfQoKCi8qIENhbGN1bGF0ZSBzaG9ydCBuYW1lIGNoZWNrc3VtICovCnN0YXRpYyBfX3U4Cm1rY2tzdW0oY29uc3QgY2hhciAqc3RyKQp7CglpbnQgaTsKCV9fdTggcmV0ID0gMDsKCglmb3IgKGkgPSAwOyBpIDwgMTE7IGkrKykgewoJCXJldCA9ICgoKHJldCYxKTw8Nyl8KChyZXQmMHhmZSk+PjEpKSArIHN0cltpXTsKCX0KCglyZXR1cm4gcmV0Owp9CiNlbmRpZgoKCi8qCiAqIEdldCB0aGUgZGlyZWN0b3J5IGVudHJ5IGFzc29jaWF0ZWQgd2l0aCAnZmlsZW5hbWUnIGZyb20gdGhlIGRpcmVjdG9yeQogKiBzdGFydGluZyBhdCAnc3RhcnRzZWN0JwogKi8KX191OCBnZXRfZGVudGZyb21kaXJfYmxvY2tbTUFYX0NMVVNUU0laRV07CnN0YXRpYyBkaXJfZW50cnkgKmdldF9kZW50ZnJvbWRpciAoZnNkYXRhICogbXlkYXRhLCBpbnQgc3RhcnRzZWN0LAoJCQkJICAgY2hhciAqZmlsZW5hbWUsIGRpcl9lbnRyeSAqIHJldGRlbnQsCgkJCQkgICBpbnQgZG9scykKewogICAgX191MTYgcHJldmNrc3VtID0gMHhmZmZmOwogICAgX191MzIgY3VyY2x1c3QgPSBTVEFSVCAocmV0ZGVudCk7CiAgICBpbnQgZmlsZXMgPSAwLCBkaXJzID0gMDsKCiAgICBGQVRfRFBSSU5UICgiZ2V0X2RlbnRmcm9tZGlyOiAlc1xuIiwgZmlsZW5hbWUpOwogICAgd2hpbGUgKDEpIHsKCWRpcl9lbnRyeSAqZGVudHB0cjsKCWludCBpOwoKCWlmIChnZXRfY2x1c3RlciAobXlkYXRhLCBjdXJjbHVzdCwgZ2V0X2RlbnRmcm9tZGlyX2Jsb2NrLAoJCSBteWRhdGEtPmNsdXN0X3NpemUgKiBTRUNUT1JfU0laRSkgIT0gMCkgewoJICAgIEZBVF9EUFJJTlQgKCJFcnJvcjogcmVhZGluZyBkaXJlY3RvcnkgYmxvY2tcbiIpOwoJICAgIHJldHVybiBOVUxMOwoJfQoJZGVudHB0ciA9IChkaXJfZW50cnkgKikgZ2V0X2RlbnRmcm9tZGlyX2Jsb2NrOwoJZm9yIChpID0gMDsgaSA8IERJUkVOVFNQRVJDTFVTVDsgaSsrKSB7CgkgICAgY2hhciBzX25hbWVbMTRdLCBsX25hbWVbMjU2XTsKCgkgICAgbF9uYW1lWzBdID0gJ1wwJzsKCSAgICBpZiAoZGVudHB0ci0+bmFtZVswXSA9PSBERUxFVEVEX0ZMQUcpIHsKCQkgICAgZGVudHB0cisrOwoJCSAgICBjb250aW51ZTsKCSAgICB9CgkgICAgaWYgKChkZW50cHRyLT5hdHRyICYgQVRUUl9WT0xVTUUpKSB7CiNpZmRlZiBDT05GSUdfU1VQUE9SVF9WRkFUCgkJaWYgKChkZW50cHRyLT5hdHRyICYgQVRUUl9WRkFUKSAmJgoJCSAgICAoZGVudHB0ci0+bmFtZVswXSAmIExBU1RfTE9OR19FTlRSWV9NQVNLKSkgewoJCSAgICBwcmV2Y2tzdW0gPSAoKGRpcl9zbG90ICopIGRlbnRwdHIpCgkJCSAgICAtPmFsaWFzX2NoZWNrc3VtOwoJCSAgICBnZXRfdmZhdG5hbWUgKG15ZGF0YSwgY3VyY2x1c3QsIGdldF9kZW50ZnJvbWRpcl9ibG9jaywKCQkJCSAgZGVudHB0ciwgbF9uYW1lKTsKCQkgICAgaWYgKGRvbHMpIHsKCQkJaW50IGlzZGlyID0gKGRlbnRwdHItPmF0dHIgJiBBVFRSX0RJUik7CgkJCWNoYXIgZGlyYzsKCQkJaW50IGRvaXQgPSAwOwoKCQkJaWYgKGlzZGlyKSB7CgkJCSAgICBkaXJzKys7CgkJCSAgICBkaXJjID0gJy8nOwoJCQkgICAgZG9pdCA9IDE7CgkJCX0gZWxzZSB7CgkJCSAgICBkaXJjID0gJyAnOwoJCQkgICAgaWYgKGxfbmFtZVswXSAhPSAwKSB7CgkJCQlmaWxlcysrOwoJCQkJZG9pdCA9IDE7CgkJCSAgICB9CgkJCX0KCQkJaWYgKGRvaXQpIHsKCQkJICAgIGlmIChkaXJjID09ICcgJykgewoJCQkJcHJpbnRmICgiICU4bGQgICAlcyVjXG4iLAoJCQkJCShsb25nKSBGQVQyQ1BVMzIgKGRlbnRwdHItPnNpemUpLAoJCQkJCWxfbmFtZSwgZGlyYyk7CgkJCSAgICB9IGVsc2UgewoJCQkJcHJpbnRmICgiICAgICAgICAgICAgJXMlY1xuIiwgbF9uYW1lLCBkaXJjKTsKCQkJICAgIH0KCQkJfQoJCQlkZW50cHRyKys7CgkJCWNvbnRpbnVlOwoJCSAgICB9CgkJICAgIEZBVF9EUFJJTlQgKCJ2ZmF0bmFtZTogfCVzfFxuIiwgbF9uYW1lKTsKCQl9IGVsc2UKI2VuZGlmCgkJewoJCSAgICAvKiBWb2x1bWUgbGFiZWwgb3IgVkZBVCBlbnRyeSAqLwoJCSAgICBkZW50cHRyKys7CgkJICAgIGNvbnRpbnVlOwoJCX0KCSAgICB9CgkgICAgaWYgKGRlbnRwdHItPm5hbWVbMF0gPT0gMCkgewoJCWlmIChkb2xzKSB7CgkJICAgIHByaW50ZiAoIlxuJWQgZmlsZShzKSwgJWQgZGlyKHMpXG5cbiIsIGZpbGVzLCBkaXJzKTsKCQl9CgkJRkFUX0RQUklOVCAoIkRlbnRuYW1lID09IE5VTEwgLSAlZFxuIiwgaSk7CgkJcmV0dXJuIE5VTEw7CgkgICAgfQojaWZkZWYgQ09ORklHX1NVUFBPUlRfVkZBVAoJICAgIGlmIChkb2xzICYmIG1rY2tzdW0gKGRlbnRwdHItPm5hbWUpID09IHByZXZja3N1bSkgewoJCWRlbnRwdHIrKzsKCQljb250aW51ZTsKCSAgICB9CiNlbmRpZgoJICAgIGdldF9uYW1lIChkZW50cHRyLCBzX25hbWUpOwoJICAgIGlmIChkb2xzKSB7CgkJaW50IGlzZGlyID0gKGRlbnRwdHItPmF0dHIgJiBBVFRSX0RJUik7CgkJY2hhciBkaXJjOwoJCWludCBkb2l0ID0gMDsKCgkJaWYgKGlzZGlyKSB7CgkJICAgIGRpcnMrKzsKCQkgICAgZGlyYyA9ICcvJzsKCQkgICAgZG9pdCA9IDE7CgkJfSBlbHNlIHsKCQkgICAgZGlyYyA9ICcgJzsKCQkgICAgaWYgKHNfbmFtZVswXSAhPSAwKSB7CgkJCWZpbGVzKys7CgkJCWRvaXQgPSAxOwoJCSAgICB9CgkJfQoJCWlmIChkb2l0KSB7CgkJICAgIGlmIChkaXJjID09ICcgJykgewoJCQlwcmludGYgKCIgJThsZCAgICVzJWNcbiIsCgkJCQkobG9uZykgRkFUMkNQVTMyIChkZW50cHRyLT5zaXplKSwgc19uYW1lLAoJCQkJZGlyYyk7CgkJICAgIH0gZWxzZSB7CgkJCXByaW50ZiAoIiAgICAgICAgICAgICVzJWNcbiIsIHNfbmFtZSwgZGlyYyk7CgkJICAgIH0KCQl9CgkJZGVudHB0cisrOwoJCWNvbnRpbnVlOwoJICAgIH0KCSAgICBpZiAoc3RyY21wIChmaWxlbmFtZSwgc19uYW1lKSAmJiBzdHJjbXAgKGZpbGVuYW1lLCBsX25hbWUpKSB7CgkJRkFUX0RQUklOVCAoIk1pc21hdGNoOiB8JXN8JXN8XG4iLCBzX25hbWUsIGxfbmFtZSk7CgkJZGVudHB0cisrOwoJCWNvbnRpbnVlOwoJICAgIH0KCSAgICBtZW1jcHkgKHJldGRlbnQsIGRlbnRwdHIsIHNpemVvZiAoZGlyX2VudHJ5KSk7CgoJICAgIEZBVF9EUFJJTlQgKCJEZW50TmFtZTogJXMiLCBzX25hbWUpOwoJICAgIEZBVF9EUFJJTlQgKCIsIHN0YXJ0OiAweCV4IiwgU1RBUlQgKGRlbnRwdHIpKTsKCSAgICBGQVRfRFBSSU5UICgiLCBzaXplOiAgMHgleCAlc1xuIiwKCQkJRkFUMkNQVTMyIChkZW50cHRyLT5zaXplKSwKCQkJKGRlbnRwdHItPmF0dHIgJiBBVFRSX0RJUikgPyAiKERJUikiIDogIiIpOwoKCSAgICByZXR1cm4gcmV0ZGVudDsKCX0KCWN1cmNsdXN0ID0gZ2V0X2ZhdGVudCAobXlkYXRhLCBjdXJjbHVzdCk7CglpZiAoY3VyY2x1c3QgPD0gMHgwMDAxIHx8IGN1cmNsdXN0ID49IDB4ZmZmMCkgewoJICAgIEZBVF9EUFJJTlQgKCJjdXJjbHVzdDogMHgleFxuIiwgY3VyY2x1c3QpOwoJICAgIEZBVF9FUlJPUiAoIkludmFsaWQgRkFUIGVudHJ5XG4iKTsKCSAgICByZXR1cm4gTlVMTDsKCX0KICAgIH0KCiAgICByZXR1cm4gTlVMTDsKfQoKCi8qCiAqIFJlYWQgYm9vdCBzZWN0b3IgYW5kIHZvbHVtZSBpbmZvIGZyb20gYSBGQVQgZmlsZXN5c3RlbQogKi8Kc3RhdGljIGludApyZWFkX2Jvb3RzZWN0YW5kdmkoYm9vdF9zZWN0b3IgKmJzLCB2b2x1bWVfaW5mbyAqdm9saW5mbywgaW50ICpmYXRzaXplKQp7CglfX3U4IGJsb2NrW0ZTX0JMT0NLX1NJWkVdOwoJdm9sdW1lX2luZm8gKnZpc3RhcnQ7CgoJaWYgKGRpc2tfcmVhZCgwLCAxLCBibG9jaykgPCAwKSB7CgkJRkFUX0RQUklOVCgiRXJyb3I6IHJlYWRpbmcgYmxvY2tcbiIpOwoJCXJldHVybiAtMTsKCX0KCgltZW1jcHkoYnMsIGJsb2NrLCBzaXplb2YoYm9vdF9zZWN0b3IpKTsKCWJzLT5yZXNlcnZlZAk9IEZBVDJDUFUxNihicy0+cmVzZXJ2ZWQpOwoJYnMtPmZhdF9sZW5ndGgJPSBGQVQyQ1BVMTYoYnMtPmZhdF9sZW5ndGgpOwoJYnMtPnNlY3NfdHJhY2sJPSBGQVQyQ1BVMTYoYnMtPnNlY3NfdHJhY2spOwoJYnMtPmhlYWRzCT0gRkFUMkNQVTE2KGJzLT5oZWFkcyk7CiNpZiAwIC8qIFVOVVNFRCAqLwoJYnMtPmhpZGRlbgk9IEZBVDJDUFUzMihicy0+aGlkZGVuKTsKI2VuZGlmCglicy0+dG90YWxfc2VjdAk9IEZBVDJDUFUzMihicy0+dG90YWxfc2VjdCk7CgoJLyogRkFUMzIgZW50cmllcyAqLwoJaWYgKGJzLT5mYXRfbGVuZ3RoID09IDApIHsKCQkvKiBBc3N1bWUgRkFUMzIgKi8KCQlicy0+ZmF0MzJfbGVuZ3RoID0gRkFUMkNQVTMyKGJzLT5mYXQzMl9sZW5ndGgpOwoJCWJzLT5mbGFncwkgPSBGQVQyQ1BVMTYoYnMtPmZsYWdzKTsKCQlicy0+cm9vdF9jbHVzdGVyID0gRkFUMkNQVTMyKGJzLT5yb290X2NsdXN0ZXIpOwoJCWJzLT5pbmZvX3NlY3RvciAgPSBGQVQyQ1BVMTYoYnMtPmluZm9fc2VjdG9yKTsKCQlicy0+YmFja3VwX2Jvb3QgID0gRkFUMkNQVTE2KGJzLT5iYWNrdXBfYm9vdCk7CgkJdmlzdGFydCA9ICh2b2x1bWVfaW5mbyopIChibG9jayArIHNpemVvZihib290X3NlY3RvcikpOwoJCSpmYXRzaXplID0gMzI7Cgl9IGVsc2UgewoJCXZpc3RhcnQgPSAodm9sdW1lX2luZm8qKSAmKGJzLT5mYXQzMl9sZW5ndGgpOwoJCSpmYXRzaXplID0gMDsKCX0KCW1lbWNweSh2b2xpbmZvLCB2aXN0YXJ0LCBzaXplb2Yodm9sdW1lX2luZm8pKTsKCgkvKiBUZXJtaW5hdGUgZnNfdHlwZSBzdHJpbmcuIFdyaXRpbmcgcGFzdCB0aGUgZW5kIG9mIHZpc3RhcnQKCSAgIGlzIG9rIC0gaXQncyBqdXN0IHRoZSBidWZmZXIuICovCgl2aXN0YXJ0LT5mc190eXBlWzhdID0gJ1wwJzsKCglpZiAoKmZhdHNpemUgPT0gMzIpIHsKCQlpZiAoY29tcGFyZV9zaWduKEZBVDMyX1NJR04sIHZpc3RhcnQtPmZzX3R5cGUpID09IDApIHsKCQkJcmV0dXJuIDA7CgkJfQoJfSBlbHNlIHsKCQlpZiAoY29tcGFyZV9zaWduKEZBVDEyX1NJR04sIHZpc3RhcnQtPmZzX3R5cGUpID09IDApIHsKCQkJKmZhdHNpemUgPSAxMjsKCQkJcmV0dXJuIDA7CgkJfQoJCWlmIChjb21wYXJlX3NpZ24oRkFUMTZfU0lHTiwgdmlzdGFydC0+ZnNfdHlwZSkgPT0gMCkgewoJCQkqZmF0c2l6ZSA9IDE2OwoJCQlyZXR1cm4gMDsKCQl9Cgl9CgoJRkFUX0RQUklOVCgiRXJyb3I6IGJyb2tlbiBmc190eXBlIHNpZ25cbiIpOwoJcmV0dXJuIC0xOwp9CgoKX191OCBkb19mYXRfcmVhZF9ibG9ja1tNQVhfQ0xVU1RTSVpFXTsgIC8qIEJsb2NrIGJ1ZmZlciAqLwpsb25nCmRvX2ZhdF9yZWFkIChjb25zdCBjaGFyICpmaWxlbmFtZSwgdm9pZCAqYnVmZmVyLCB1bnNpZ25lZCBsb25nIG1heHNpemUsCgkgICAgIGludCBkb2xzKQp7CiNpZiBDT05GSUdfTklPUyAvKiBOSU9TIENQVSBjYW5ub3QgYWNjZXNzIGJpZyBhdXRvbWF0aWMgYXJyYXlzICovCiAgICBzdGF0aWMKI2VuZGlmCiAgICBjaGFyIGZuYW1lY29weVsyMDQ4XTsKICAgIGJvb3Rfc2VjdG9yIGJzOwogICAgdm9sdW1lX2luZm8gdm9saW5mbzsKICAgIGZzZGF0YSBkYXRhYmxvY2s7CiAgICBmc2RhdGEgKm15ZGF0YSA9ICZkYXRhYmxvY2s7CiAgICBkaXJfZW50cnkgKmRlbnRwdHI7CiAgICBfX3UxNiBwcmV2Y2tzdW0gPSAweGZmZmY7CiAgICBjaGFyICpzdWJuYW1lID0gIiI7CiAgICBpbnQgcm9vdGRpcl9zaXplLCBjdXJzZWN0OwogICAgaW50IGlkeCwgaXNkaXIgPSAwOwogICAgaW50IGZpbGVzID0gMCwgZGlycyA9IDA7CiAgICBsb25nIHJldCA9IDA7CiAgICBpbnQgZmlyc3R0aW1lOwoKICAgIGlmIChyZWFkX2Jvb3RzZWN0YW5kdmkgKCZicywgJnZvbGluZm8sICZteWRhdGEtPmZhdHNpemUpKSB7CglGQVRfRFBSSU5UICgiRXJyb3I6IHJlYWRpbmcgYm9vdCBzZWN0b3JcbiIpOwoJcmV0dXJuIC0xOwogICAgfQogICAgaWYgKG15ZGF0YS0+ZmF0c2l6ZSA9PSAzMikgewoJbXlkYXRhLT5mYXRsZW5ndGggPSBicy5mYXQzMl9sZW5ndGg7CiAgICB9IGVsc2UgewoJbXlkYXRhLT5mYXRsZW5ndGggPSBicy5mYXRfbGVuZ3RoOwogICAgfQogICAgbXlkYXRhLT5mYXRfc2VjdCA9IGJzLnJlc2VydmVkOwogICAgY3Vyc2VjdCA9IG15ZGF0YS0+cm9vdGRpcl9zZWN0CgkgICAgPSBteWRhdGEtPmZhdF9zZWN0ICsgbXlkYXRhLT5mYXRsZW5ndGggKiBicy5mYXRzOwogICAgbXlkYXRhLT5jbHVzdF9zaXplID0gYnMuY2x1c3Rlcl9zaXplOwogICAgaWYgKG15ZGF0YS0+ZmF0c2l6ZSA9PSAzMikgewoJcm9vdGRpcl9zaXplID0gbXlkYXRhLT5jbHVzdF9zaXplOwoJbXlkYXRhLT5kYXRhX2JlZ2luID0gbXlkYXRhLT5yb290ZGlyX3NlY3QgICAvKiArIHJvb3RkaXJfc2l6ZSAqLwoJCS0gKG15ZGF0YS0+Y2x1c3Rfc2l6ZSAqIDIpOwogICAgfSBlbHNlIHsKCXJvb3RkaXJfc2l6ZSA9ICgoYnMuZGlyX2VudHJpZXNbMV0gKiAoaW50KSAyNTYgKyBicy5kaXJfZW50cmllc1swXSkKCQkJKiBzaXplb2YgKGRpcl9lbnRyeSkpIC8gU0VDVE9SX1NJWkU7CglteWRhdGEtPmRhdGFfYmVnaW4gPSBteWRhdGEtPnJvb3RkaXJfc2VjdCArIHJvb3RkaXJfc2l6ZQoJCS0gKG15ZGF0YS0+Y2x1c3Rfc2l6ZSAqIDIpOwogICAgfQogICAgbXlkYXRhLT5mYXRidWZudW0gPSAtMTsKCiAgICBGQVRfRFBSSU5UICgiRkFUJWQsIGZhdGxlbmd0aDogJWRcbiIsIG15ZGF0YS0+ZmF0c2l6ZSwKCQlteWRhdGEtPmZhdGxlbmd0aCk7CiAgICBGQVRfRFBSSU5UICgiUm9vdGRpciBiZWdpbnMgYXQgc2VjdG9yOiAlZCwgb2Zmc2V0OiAleCwgc2l6ZTogJWRcbiIKCQkiRGF0YSBiZWdpbnMgYXQ6ICVkXG4iLAoJCW15ZGF0YS0+cm9vdGRpcl9zZWN0LCBteWRhdGEtPnJvb3RkaXJfc2VjdCAqIFNFQ1RPUl9TSVpFLAoJCXJvb3RkaXJfc2l6ZSwgbXlkYXRhLT5kYXRhX2JlZ2luKTsKICAgIEZBVF9EUFJJTlQgKCJDbHVzdGVyIHNpemU6ICVkXG4iLCBteWRhdGEtPmNsdXN0X3NpemUpOwoKICAgIC8qICJjd2QiIGlzIGFsd2F5cyB0aGUgcm9vdC4uLiAqLwogICAgd2hpbGUgKElTRElSREVMSU0gKCpmaWxlbmFtZSkpCglmaWxlbmFtZSsrOwogICAgLyogTWFrZSBhIGNvcHkgb2YgdGhlIGZpbGVuYW1lIGFuZCBjb252ZXJ0IGl0IHRvIGxvd2VyY2FzZSAqLwogICAgc3RyY3B5IChmbmFtZWNvcHksIGZpbGVuYW1lKTsKICAgIGRvd25jYXNlIChmbmFtZWNvcHkpOwogICAgaWYgKCpmbmFtZWNvcHkgPT0gJ1wwJykgewoJaWYgKCFkb2xzKQoJICAgIHJldHVybiAtMTsKCWRvbHMgPSBMU19ST09UOwogICAgfSBlbHNlIGlmICgoaWR4ID0gZGlyZGVsaW0gKGZuYW1lY29weSkpID49IDApIHsKCWlzZGlyID0gMTsKCWZuYW1lY29weVtpZHhdID0gJ1wwJzsKCXN1Ym5hbWUgPSBmbmFtZWNvcHkgKyBpZHggKyAxOwoJLyogSGFuZGxlIG11bHRpcGxlIGRlbGltaXRlcnMgKi8KCXdoaWxlIChJU0RJUkRFTElNICgqc3VibmFtZSkpCgkgICAgc3VibmFtZSsrOwogICAgfSBlbHNlIGlmIChkb2xzKSB7Cglpc2RpciA9IDE7CiAgICB9CgogICAgd2hpbGUgKDEpIHsKCWludCBpOwoKCWlmIChkaXNrX3JlYWQgKGN1cnNlY3QsIG15ZGF0YS0+Y2x1c3Rfc2l6ZSwgZG9fZmF0X3JlYWRfYmxvY2spIDwgMCkgewoJICAgIEZBVF9EUFJJTlQgKCJFcnJvcjogcmVhZGluZyByb290ZGlyIGJsb2NrXG4iKTsKCSAgICByZXR1cm4gLTE7Cgl9CglkZW50cHRyID0gKGRpcl9lbnRyeSAqKSBkb19mYXRfcmVhZF9ibG9jazsKCWZvciAoaSA9IDA7IGkgPCBESVJFTlRTUEVSQkxPQ0s7IGkrKykgewoJICAgIGNoYXIgc19uYW1lWzE0XSwgbF9uYW1lWzI1Nl07CgoJICAgIGxfbmFtZVswXSA9ICdcMCc7CgkgICAgaWYgKChkZW50cHRyLT5hdHRyICYgQVRUUl9WT0xVTUUpKSB7CiNpZmRlZiBDT05GSUdfU1VQUE9SVF9WRkFUCgkJaWYgKChkZW50cHRyLT5hdHRyICYgQVRUUl9WRkFUKSAmJgoJCSAgICAoZGVudHB0ci0+bmFtZVswXSAmIExBU1RfTE9OR19FTlRSWV9NQVNLKSkgewoJCSAgICBwcmV2Y2tzdW0gPSAoKGRpcl9zbG90ICopIGRlbnRwdHIpLT5hbGlhc19jaGVja3N1bTsKCQkgICAgZ2V0X3ZmYXRuYW1lIChteWRhdGEsIDAsIGRvX2ZhdF9yZWFkX2Jsb2NrLCBkZW50cHRyLCBsX25hbWUpOwoJCSAgICBpZiAoZG9scyA9PSBMU19ST09UKSB7CgkJCWludCBpc2RpciA9IChkZW50cHRyLT5hdHRyICYgQVRUUl9ESVIpOwoJCQljaGFyIGRpcmM7CgkJCWludCBkb2l0ID0gMDsKCgkJCWlmIChpc2RpcikgewoJCQkgICAgZGlycysrOwoJCQkgICAgZGlyYyA9ICcvJzsKCQkJICAgIGRvaXQgPSAxOwoJCQl9IGVsc2UgewoJCQkgICAgZGlyYyA9ICcgJzsKCQkJICAgIGlmIChsX25hbWVbMF0gIT0gMCkgewoJCQkJZmlsZXMrKzsKCQkJCWRvaXQgPSAxOwoJCQkgICAgfQoJCQl9CgkJCWlmIChkb2l0KSB7CgkJCSAgICBpZiAoZGlyYyA9PSAnICcpIHsKCQkJCXByaW50ZiAoIiAlOGxkICAgJXMlY1xuIiwKCQkJCQkobG9uZykgRkFUMkNQVTMyIChkZW50cHRyLT5zaXplKSwKCQkJCQlsX25hbWUsIGRpcmMpOwoJCQkgICAgfSBlbHNlIHsKCQkJCXByaW50ZiAoIiAgICAgICAgICAgICVzJWNcbiIsIGxfbmFtZSwgZGlyYyk7CgkJCSAgICB9CgkJCX0KCQkJZGVudHB0cisrOwoJCQljb250aW51ZTsKCQkgICAgfQoJCSAgICBGQVRfRFBSSU5UICgiUm9vdHZmYXRuYW1lOiB8JXN8XG4iLCBsX25hbWUpOwoJCX0gZWxzZQojZW5kaWYKCQl7CgkJICAgIC8qIFZvbHVtZSBsYWJlbCBvciBWRkFUIGVudHJ5ICovCgkJICAgIGRlbnRwdHIrKzsKCQkgICAgY29udGludWU7CgkJfQoJICAgIH0gZWxzZSBpZiAoZGVudHB0ci0+bmFtZVswXSA9PSAwKSB7CgkJRkFUX0RQUklOVCAoIlJvb3REZW50bmFtZSA9PSBOVUxMIC0gJWRcbiIsIGkpOwoJCWlmIChkb2xzID09IExTX1JPT1QpIHsKCQkgICAgcHJpbnRmICgiXG4lZCBmaWxlKHMpLCAlZCBkaXIocylcblxuIiwgZmlsZXMsIGRpcnMpOwoJCSAgICByZXR1cm4gMDsKCQl9CgkJcmV0dXJuIC0xOwoJICAgIH0KI2lmZGVmIENPTkZJR19TVVBQT1JUX1ZGQVQKCSAgICBlbHNlIGlmIChkb2xzID09IExTX1JPT1QKCQkgICAgICYmIG1rY2tzdW0gKGRlbnRwdHItPm5hbWUpID09IHByZXZja3N1bSkgewoJCWRlbnRwdHIrKzsKCQljb250aW51ZTsKCSAgICB9CiNlbmRpZgoJICAgIGdldF9uYW1lIChkZW50cHRyLCBzX25hbWUpOwoJICAgIGlmIChkb2xzID09IExTX1JPT1QpIHsKCQlpbnQgaXNkaXIgPSAoZGVudHB0ci0+YXR0ciAmIEFUVFJfRElSKTsKCQljaGFyIGRpcmM7CgkJaW50IGRvaXQgPSAwOwoKCQlpZiAoaXNkaXIpIHsKCQkgICAgZGlyYyA9ICcvJzsKCQkgICAgaWYgKHNfbmFtZVswXSAhPSAwKSB7CgkJCWRpcnMrKzsKCQkJZG9pdCA9IDE7CgkJICAgIH0KCQl9IGVsc2UgewoJCSAgICBkaXJjID0gJyAnOwoJCSAgICBpZiAoc19uYW1lWzBdICE9IDApIHsKCQkJZmlsZXMrKzsKCQkJZG9pdCA9IDE7CgkJICAgIH0KCQl9CgkJaWYgKGRvaXQpIHsKCQkgICAgaWYgKGRpcmMgPT0gJyAnKSB7CgkJCXByaW50ZiAoIiAlOGxkICAgJXMlY1xuIiwKCQkJCShsb25nKSBGQVQyQ1BVMzIgKGRlbnRwdHItPnNpemUpLCBzX25hbWUsCgkJCQlkaXJjKTsKCQkgICAgfSBlbHNlIHsKCQkJcHJpbnRmICgiICAgICAgICAgICAgJXMlY1xuIiwgc19uYW1lLCBkaXJjKTsKCQkgICAgfQoJCX0KCQlkZW50cHRyKys7CgkJY29udGludWU7CgkgICAgfQoJICAgIGlmIChzdHJjbXAgKGZuYW1lY29weSwgc19uYW1lKSAmJiBzdHJjbXAgKGZuYW1lY29weSwgbF9uYW1lKSkgewoJCUZBVF9EUFJJTlQgKCJSb290TWlzbWF0Y2g6IHwlc3wlc3xcbiIsIHNfbmFtZSwgbF9uYW1lKTsKCQlkZW50cHRyKys7CgkJY29udGludWU7CgkgICAgfQoJICAgIGlmIChpc2RpciAmJiAhKGRlbnRwdHItPmF0dHIgJiBBVFRSX0RJUikpCgkJcmV0dXJuIC0xOwoKCSAgICBGQVRfRFBSSU5UICgiUm9vdE5hbWU6ICVzIiwgc19uYW1lKTsKCSAgICBGQVRfRFBSSU5UICgiLCBzdGFydDogMHgleCIsIFNUQVJUIChkZW50cHRyKSk7CgkgICAgRkFUX0RQUklOVCAoIiwgc2l6ZTogIDB4JXggJXNcbiIsCgkJCUZBVDJDUFUzMiAoZGVudHB0ci0+c2l6ZSksIGlzZGlyID8gIihESVIpIiA6ICIiKTsKCgkgICAgZ290byByb290ZGlyX2RvbmU7ICAvKiBXZSBnb3QgYSBtYXRjaCAqLwoJfQoJY3Vyc2VjdCsrOwogICAgfQogIHJvb3RkaXJfZG9uZToKCiAgICBmaXJzdHRpbWUgPSAxOwogICAgd2hpbGUgKGlzZGlyKSB7CglpbnQgc3RhcnRzZWN0ID0gbXlkYXRhLT5kYXRhX2JlZ2luCgkJKyBTVEFSVCAoZGVudHB0cikgKiBteWRhdGEtPmNsdXN0X3NpemU7CglkaXJfZW50cnkgZGVudDsKCWNoYXIgKm5leHRuYW1lID0gTlVMTDsKCglkZW50ID0gKmRlbnRwdHI7CglkZW50cHRyID0gJmRlbnQ7CgoJaWR4ID0gZGlyZGVsaW0gKHN1Ym5hbWUpOwoJaWYgKGlkeCA+PSAwKSB7CgkgICAgc3VibmFtZVtpZHhdID0gJ1wwJzsKCSAgICBuZXh0bmFtZSA9IHN1Ym5hbWUgKyBpZHggKyAxOwoJICAgIC8qIEhhbmRsZSBtdWx0aXBsZSBkZWxpbWl0ZXJzICovCgkgICAgd2hpbGUgKElTRElSREVMSU0gKCpuZXh0bmFtZSkpCgkJbmV4dG5hbWUrKzsKCSAgICBpZiAoZG9scyAmJiAqbmV4dG5hbWUgPT0gJ1wwJykKCQlmaXJzdHRpbWUgPSAwOwoJfSBlbHNlIHsKCSAgICBpZiAoZG9scyAmJiBmaXJzdHRpbWUpIHsKCQlmaXJzdHRpbWUgPSAwOwoJICAgIH0gZWxzZSB7CgkJaXNkaXIgPSAwOwoJICAgIH0KCX0KCglpZiAoZ2V0X2RlbnRmcm9tZGlyIChteWRhdGEsIHN0YXJ0c2VjdCwgc3VibmFtZSwgZGVudHB0ciwKCQkJICAgICBpc2RpciA/IDAgOiBkb2xzKSA9PSBOVUxMKSB7CgkgICAgaWYgKGRvbHMgJiYgIWlzZGlyKQoJCXJldHVybiAwOwoJICAgIHJldHVybiAtMTsKCX0KCglpZiAoaWR4ID49IDApIHsKCSAgICBpZiAoIShkZW50cHRyLT5hdHRyICYgQVRUUl9ESVIpKQoJCXJldHVybiAtMTsKCSAgICBzdWJuYW1lID0gbmV4dG5hbWU7Cgl9CiAgICB9CiAgICByZXQgPSBnZXRfY29udGVudHMgKG15ZGF0YSwgZGVudHB0ciwgYnVmZmVyLCBtYXhzaXplKTsKICAgIEZBVF9EUFJJTlQgKCJTaXplOiAlZCwgZ290OiAlbGRcbiIsIEZBVDJDUFUzMiAoZGVudHB0ci0+c2l6ZSksIHJldCk7CgogICAgcmV0dXJuIHJldDsKfQoKCmludApmaWxlX2ZhdF9kZXRlY3Rmcyh2b2lkKQp7Cglib290X3NlY3RvcgliczsKCXZvbHVtZV9pbmZvCXZvbGluZm87CglpbnQJCWZhdHNpemU7CgljaGFyCXZvbF9sYWJlbFsxMl07CgoJaWYoY3VyX2Rldj09TlVMTCkgewoJCXByaW50ZigiTm8gY3VycmVudCBkZXZpY2VcbiIpOwoJCXJldHVybiAxOwoJfQojaWYgKENPTkZJR19DT01NQU5EUyAmIENGR19DTURfSURFKSB8fCAoQ09ORklHX0NPTU1BTkRTICYgQ0ZHX0NNRF9TQ1NJKSB8fCBcCiAgICAoQ09ORklHX0NPTU1BTkRTICYgQ0ZHX0NNRF9VU0IpIHx8IChDT05GSUdfTU1DKQoJcHJpbnRmKCJJbnRlcmZhY2U6ICAiKTsKCXN3aXRjaChjdXJfZGV2LT5pZl90eXBlKSB7CgkJY2FzZSBJRl9UWVBFX0lERSA6CXByaW50ZigiSURFIik7IGJyZWFrOwoJCWNhc2UgSUZfVFlQRV9TQ1NJIDoJcHJpbnRmKCJTQ1NJIik7IGJyZWFrOwoJCWNhc2UgSUZfVFlQRV9BVEFQSSA6CXByaW50ZigiQVRBUEkiKTsgYnJlYWs7CgkJY2FzZSBJRl9UWVBFX1VTQiA6CXByaW50ZigiVVNCIik7IGJyZWFrOwoJCWNhc2UgSUZfVFlQRV9ET0MgOglwcmludGYoIkRPQyIpOyBicmVhazsKCQljYXNlIElGX1RZUEVfTU1DIDoJcHJpbnRmKCJNTUMiKTsgYnJlYWs7CgkJZGVmYXVsdCA6CQlwcmludGYoIlVua25vd24iKTsKCX0KCXByaW50ZigiXG4gIERldmljZSAlZDogIixjdXJfZGV2LT5kZXYpOwoJZGV2X3ByaW50KGN1cl9kZXYpOwojZW5kaWYKCWlmKHJlYWRfYm9vdHNlY3RhbmR2aSgmYnMsICZ2b2xpbmZvLCAmZmF0c2l6ZSkpIHsKCQlwcmludGYoIlxuTm8gdmFsaWQgRkFUIGZzIGZvdW5kXG4iKTsKCQlyZXR1cm4gMTsKCX0KCW1lbWNweSAodm9sX2xhYmVsLCB2b2xpbmZvLnZvbHVtZV9sYWJlbCwgMTEpOwoJdm9sX2xhYmVsWzExXSA9ICdcMCc7Cgl2b2xpbmZvLmZzX3R5cGVbNV09J1wwJzsKCXByaW50ZigiUGFydGl0aW9uICVkOiBGaWxlc3lzdGVtOiAlcyBcIiVzXCJcbiIsY3VyX3BhcnQsdm9saW5mby5mc190eXBlLHZvbF9sYWJlbCk7CglyZXR1cm4gMDsKfQoKCmludApmaWxlX2ZhdF9scyhjb25zdCBjaGFyICpkaXIpCnsKCXJldHVybiBkb19mYXRfcmVhZChkaXIsIE5VTEwsIDAsIExTX1lFUyk7Cn0KCgpsb25nCmZpbGVfZmF0X3JlYWQoY29uc3QgY2hhciAqZmlsZW5hbWUsIHZvaWQgKmJ1ZmZlciwgdW5zaWduZWQgbG9uZyBtYXhzaXplKQp7CglwcmludGYoInJlYWRpbmcgJXNcbiIsZmlsZW5hbWUpOwoJcmV0dXJuIGRvX2ZhdF9yZWFkKGZpbGVuYW1lLCBidWZmZXIsIG1heHNpemUsIExTX05PKTsKfQoKI2VuZGlmIC8qICNpZiAoQ09ORklHX0NPTU1BTkRTICYgQ0ZHX0NNRF9GQVQpICovCg==